NYOJ 571 —— 各种划分数

Posted SuperChan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NYOJ 571 —— 各种划分数相关的知识,希望对你有一定的参考价值。

整数划分(三)

时间限制:1000 ms  |  内存限制:65535 KB 
描述

整数划分是一个经典的问题。请写一个程序,完成以下要求。

输入
每组输入是两个整数n和k。(1 <= n <= 50, 1 <= k <= n)
输出
对于输入的 n,k;
第一行: 将n划分成若干正整数之和的划分数。
第二行: 将n划分成k个正整数之和的划分数。
第三行: 将n划分成最大数不超过k的划分数。
第四行: 将n划分成若干个 奇正整数之和的划分数。
第五行: 将n划分成若干不同整数之和的划分数。
第六行: 打印一个空行
样例输入
5 2
样例输出
7
2
3
3
3
提示
样例输出提示:
1.将5划分成若干正整数之和的划分为: 5, 4+1, 3+2, 3+1+1, 2+2+1, 2+1+1+1, 1+1+1+1+1
2.将5划分成2个正整数之和的划分为: 3+2, 4+1
3.将5划分成最大数不超过2的划分为: 1+1+1+1+1, 1+1+1+2, 1+2+2
4.将5划分成若干 奇正整数之和的划分为: 5, 1+1+3, 1+1+1+1+1
5.将5划分成若干不同整数之和的划分为: 5, 1+4, 2+3

 

#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
using namespace std;

int dp[55][55];

int main ()
{
    int n, k, a, b, c, d, e;
    while(scanf("%d%d", &n, &k) != EOF) {
        // 把正整数i划分为不超过j的正整数的划分个数
        for(int i=1; i<=n; i++) {
            for(int j=1; j<=n; j++) {
                if(j>i)    dp[i][j] = dp[i][i];
                else if(j == i)    dp[i][j] = dp[i][j-1] + 1;
                else    dp[i][j] = dp[i][j-1] + dp[i-j][j];
            }
        }
        a = dp[n][n];
        c = dp[n][k];
        
        // 把正整数划分为k个正整数的划分个数
        for(int i=1; i<=n; i++) {
            for(int j=1; j<=k; j++) {
                if(j>i)    dp[i][j] = 0;
                else if(j==i)    dp[i][j] = 1;
                else    dp[i][j] = dp[i-1][j-1] + dp[i-j][j];
            }
        }
        b = dp[n][k];
        
        
        // 把i划分为不超过j的奇数的划分个数
        int odd = n&1 ? n : n-1;
        for(int i=1; i<=n; i++) {
            dp[i][1] = 1;
            for(int j=3; j<=odd; j+=2) {
                if(j>i) {
                    if(i&1)    dp[i][j] = dp[i][i];
                    else    dp[i][j] = dp[i][i-1];
                }
                else if(j==i)    dp[i][j] = dp[i][i-2] + 1;
                else    dp[i][j] = dp[i][j-2] + dp[i-j][j];
            }
        }
        d = dp[n][odd];
        
        // 把i划分为不同正整数的划分个数
        for(int i=1; i<=n; i++) {
            for(int j=1; j<=n; j++) {
                if(j>i)    dp[i][j] = dp[i][i];
                else if(j == i)    dp[i][j] = dp[i][i-1] + 1;
                else    dp[i][j] = dp[i][j-1] + dp[i-j][j-1];
            }
        }
        e = dp[n][n];
              
        printf("%d\n%d\n%d\n%d\n%d\n\n", a, b, c, d, e);
        memset(dp, 0, sizeof(dp));
    }
    
    return 0;
}

 

以上是关于NYOJ 571 —— 各种划分数的主要内容,如果未能解决你的问题,请参考以下文章

NYOJ 90 —— 求n划分为若干个正整数的划分个数

NYOJ 1103 —— m划分为n个正整数的个数

nyoj746 整数划分

NYOJ - 整数划分

NYOJ746 整数划分

NYOJ 746 - 正整数n划分为m段,求m段的最大乘积 区间DP