动态规划例子

对于由从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);  
        }  
      
      
    }  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值