百练 03 复杂的整数划分问题

百练 03 复杂的整数划分问题

总时间限制: 内存限制:
200ms 65536kB

描述

将正整数 n 表示成一系列正整数之和, n=n1+n2++nk , 其中 n1>=n2>=>=nk>=1k>=1
正整数 n 的这种表示称为正整数 n 的划分。

输入

标准的输入包含若干组测试数据。每组测试数据是一行输入数据,包括两个整数 N K
(0<N<=50,0<K<=N)

输出

对于每组测试数据,输出以下三行数据:

  • 第一行: N划分成K个正整数之和的划分数目

  • 第二行: N划分成若干个不同正整数之和的划分数目

  • 第三行: N划分成若干个奇正整数之和的划分数目

样例输入

5 2

样例输出

2
3
3

提示

  • 第一行: 4+1, 3+2,
  • 第二行: 5,4+1,3+2
  • 第三行: 5,1+1+3, 1+1+1+1+1+1

参考:整数划分问题

#include 
#include 
#include 

using namespace std;

const int MAX_NUM = 50 + 5;

int N, K;
int dp[MAX_NUM][MAX_NUM];
int g[MAX_NUM][MAX_NUM];
int f[MAX_NUM][MAX_NUM];

int main() {
    while(scanf("%d%d", &N, &K) != EOF) {
        // N划分成K个正整数之和的划分数目
        memset(dp, 0, sizeof(dp));
        // dp(i,j)表示正整数i划分成j个正整数
        dp[0][0] = 1;
        for(int i = 1; i <= N; i++) {
            for(int j = 1; j <= N; j++) {
                if(i < j) {
                    dp[i][j] = 0;
                } else if(i > j){
                    dp[i][j] = dp[i - 1][j - 1] + dp[i - j][j];
                } else {
                    dp[i][j] = 1;
                }
            }
        }
        cout << dp[N][K] << endl;

        // N划分成若干个不同正整数之和的划分数目
        memset(dp, 0, sizeof(dp));
        // dp(i,j)表示正整数i划分为不超过j的不同整数的划分数
        dp[0][0] = 1;
        for(int i = 1; i <= N; i++) {
            for(int j = 1; j <= N; j++) {
                if(i < j) {
                    dp[i][j] = dp[i][i];
                } else if(i > j) {
                    dp[i][j] = dp[i - j][j - 1] + dp[i][j - 1];
                } else {
                    dp[i][j] = dp[i][j - 1] + 1;
                }
            }
        }
        cout << dp[N][N] << endl;

        // N划分成若干个奇正整数之和的划分数目
        memset(g, 0, sizeof(g));
        memset(f, 0, sizeof(f));
        // f(i,j)表示正整数i划分为j个奇数之和的划分数
        // g(i,j)表示正整数i划分为j个偶数之和的划分数
        f[0][0] = g[0][0] = 1;
        for(int i = 1; i <= N; i++) {
            for(int j = 1; j <= i; j++) {
                g[i][j] = f[i - j][j];
                f[i][j] = f[i - 1][j - 1] + g[i - j][j];
            }
        }
        int num = 0;
        for(int i = 0; i <= N; i++) {
            num += f[N][i];
        }
        cout << num << endl;
    }
    return 0;
}

你可能感兴趣的:(ACM)