您的位置:首页 > 其它

动态规划例子

2014-12-27 15:01 295 查看
对于由从1到N (1 <= N <= 39)这N个连续的整数组成的集合来说,我们有时可以将集合分成两个部分和相同的子集合。

例如,N=3时,可以将集合{1, 2, 3} 分为{1,2}和{3}。此时称有一种方式(即与顺序无关)。

N=7时,共有四种方式可以将集合{1, 2, 3, ..., 7} 分为两个部分和相同的子集合:

{1,6,7} 和 {2,3,4,5} 

{2,5,7} 和 {1,3,4,6} 

{3,4,7} 和 {1,2,5,6} 

{1,2,4,7} 和 {3,5,6} 

输入:程序从标准输入读入数据,只有一组测试用例。如上所述的N。

输出:方式数。若不存在这样的拆分,则输出0。

对于从1到N的连续整集合,划分为两个子集合,且保证每个集合的数字和

是相等的。因而,划分之后每个子集全的数字应该为n*(n+1)/2的一半,即n*(n+1)/4

由于两个子集中都是整数,所以n*(n+1)必为偶数,则可以设s=n*(n+1),并判断s%4 .

则,s/=4是划分之后子集合的数字和;dyn[i]数组表示任意个数加起来等于i的组数*/

num[0][0] 保持中间值

1  多阶段最优子结构

2 重复计算子问题

状态转移方程 

i>j

num[i][j] = num[i-1][j] + num[i-1][j-i];          

   else                     num[i][j] = num[i-1][j]; 

代码实现:

#include<stdio.h>

void main(){

int i,j,x,y,flag,sum;
int input,outresult;
int num[40][410] = {0};
num[0][0] = 1;

scanf("%d",&input);

x = input, y = (1 + input)*input/2;
sum = y/2;

flag = y%2;

if(flag == 1)
printf("0\n");

else{
for(i=1;i<=x;i++){
for(j=1;j<=y/2;j++)
if(i<=j)
num[i][j] = num[i-1][j] + num[i-1][j-i];
else
num[i][j] = num[i-1][j];
}

outresult = num[x][sum];
printf("%d\n",outresult);
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: