标签:closed int out play cout 技术分享 contract i++ using
本题应该有两种方法:
1.母函数法
2.递推法
母函数不了解,待充分了解之后,再进行补充!
这里为递推实现的方法:
思路:
定义:n为要拆分的整数;
k为拆分的项数;
f[n][k]代表 n的整数拆分中,最大项不超过k的方案数。
每一个整数n的拆分中,总有一项拆分为自己,即:n = n; 我们将其表示为f[n][1],而且f[n][1] = 1;
又,每一个整数n的拆分中,总有一项拆分为n个1,即:n = 1 + 1 + ...... + 1(n个1的加和); 我们将其表示为f[0][0],且f[0][0] = 1;(注:n = 1时除外)。
所以:
1 = 1;
f[1][1] = 1;
2 = 2;
2 = 1 + 1;
f[2][2] = f[0][0] + f[2][1] = 2;
n = 3时,
3 = 3;
3 = 2 + 1;//3 = (1+ 1) + 1;
3 = 1 + 1 + 1;
f[3][1] = 1;
f[3][2] = 拆分为两项的 数目 + 拆分为一项的 数目 = f[1][1] + f[3][1]; 之所以用f[1][1]在此表示,是因为分成两项时,以1+1作为基底数,然后向上加数,能加的数只有1,加到哪一项上都是一样的,所以就相当于f[1][1]的效果。
同理,n = 4时,
4 = 4;
4 = 3 + 1;
4 = 2 + 2;
4 = 2 + 1 + 1;
4 = 1 + 1 + 1 + 1;
像:f[4][2] = f[2][2] + f[4][1];
所以,结论就是:
对于任意满足条件的拆分,最大项要么达到k这个限制,要么小于它,因此f(n, k) = f(n-k, k) + f(n, k - 1)。
边界条件:f(n, 1) = 1, f(0, 0) = 1, f(1, 1) = 1, 另外,f(n, k) = f(n, n),如果k大于n的话。
实现代码:
1 #include <iostream> 2 using namespace std; 3 4 const int MAX = 125; 5 int f[MAX][MAX] = {0}; 6 void Init() 7 { 8 f[0][0] = 1; 9 for(int i = 1;i<MAX;i++) 10 f[i][1] = 1; 11 for(int n = 2;n<MAX;n++) 12 { 13 for(int k = 2;k<=n;k++) 14 { 15 int j; 16 if(n-k<k) 17 j = n-k; 18 else 19 j = k; 20 f[n][k] = f[n-k][j] + f[n][k-1]; 21 } 22 } 23 } 24 int main() 25 { 26 Init(); 27 int n; 28 while(cin>>n) 29 { 30 cout<<f[n][n]<<endl; 31 } 32 return 0; 33 }
1028:Ignatius and the Princess III
标签:closed int out play cout 技术分享 contract i++ using
原文地址:http://www.cnblogs.com/ttzm/p/6103880.html