主题:[讨论]求正整数n划分为k个数的和的划分数
hitsoft
[专家分:280] 发布于 2007-03-13 14:35:00
比如5,如果划分为2个数的和,可以有2种划分:1+4,2+3.
输入: 5 2
输出: 2
这题大家有什么想法呀,我想了挺久,都没想出来。
用组合去解,很容易把重复的也算进去。如果用DP,又不知道该怎么DP,晕了。
回复列表 (共14个回复)
11 楼
ttuurr [专家分:70] 发布于 2007-03-17 05:40:00
楼主编写出来了吗(按上面的思路)?
我觉得不对啊,题目是k个数,而你的是求将n表示为不超过k的正整数之和
12 楼
ttuurr [专家分:70] 发布于 2007-03-17 06:33:00
按照楼主的思路编制程序如下:
/*
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 楼
rickone [专家分:15390] 发布于 2007-03-17 10:20:00
用LZ的方法我在另外那帖里已经编了,在算n,k的时候,调入的参数是n-k,k,算(n-k)*k次加法。
14 楼
hitsoft [专家分:280] 发布于 2007-04-07 17:09:00
已经解决了,仍是谢谢各位。
我来回复