回 帖 发 新 帖 刷新版面

主题:[讨论]求正整数n划分为k个数的和的划分数

比如5,如果划分为2个数的和,可以有2种划分:1+4,2+3.
输入: 5 2
输出: 2
这题大家有什么想法呀,我想了挺久,都没想出来。
用组合去解,很容易把重复的也算进去。如果用DP,又不知道该怎么DP,晕了。

回复列表 (共14个回复)

11 楼

楼主编写出来了吗(按上面的思路)?
我觉得不对啊,题目是k个数,而你的是求将n表示为不超过k的正整数之和

12 楼

按照楼主的思路编制程序如下:
/*
f(n,k)表示整数n划分为最大数不超过k的划分数.
f(n,k)=f(n-k,k)+f(n,k-1);
边界:f(n,k) = 1,          若 n=1或k=1
               f(n,n),     若 n<k
          1+f(n,k-1),  若 n=k
*/

// 第一种方法:递归
int f(int n, int k) {
    if(n==1 || k==1)
        return 1;
    if(n<k)
        return f(n,n);
    if(n==k)
        return 1+f(n,k-1);
    return f(n-k,k)+f(n,k-1);
}

// 第二种方法
const int MAXN=1000;
const int MAXK=605;
int a[MAXN+1][MAXK+1];

int g(int n, int k) {
    for(int i=1; i<=k; i++)
        a[1][i]=1;
    for(i=2; i<=n; i++)
        a[i][1]=1;
    for(i=2; i<=n; i++)
        for(int j=2; j<=k; j++) {
            if(i<j)
                 a[i][j]=a[i][i];
            else if(i==j)
                 a[i][j]=1+a[i][j-1];
            else
                 a[i][j]=a[i-j][j]+a[i][j-1];
    }
    return a[n][k];
}

int main() {
    int n,k;
    cin>>n>>k;
    if(n>MAXN || k>MAXK) {
        cout<<"超出表示范围";
        return -1;
    }
    cout<<g(n,k)<<endl;
    cout<<f(n,k)<<endl;
}
//当n=5, k=2时,输出3

13 楼

用LZ的方法我在另外那帖里已经编了,在算n,k的时候,调入的参数是n-k,k,算(n-k)*k次加法。

14 楼

已经解决了,仍是谢谢各位。

我来回复

您尚未登录,请登录后再回复。点此登录或注册