POJ 1014 Dividing(2007-08-03 23:25)

放了好~~~久的一道题. 以前总看着没办法, 现在回头看, 感觉也不那么难了. 就是个DP.

刚开始写的代码TLE了, 后来加强了一下判断, 优化后15MS AC.

设dp[i]为价值i的可达性. 初始dp[0]=1;

把总价值sum除2, 除不尽则不能划分. 否则dp[sum/2]为所求

挺显而易见的DP...

#include "stdio.h"
#include "string.h"

char dp[60001];

int mar[7];

int main()
{
//     freopen("1.in","r",stdin);
     int c=0;
     while(++c){
         int i,j,k;
         int sum=0;
         for(i=1;i< =6;++i){
             scanf("%d",&mar[i]);
             sum+=mar[i]*i;
         }
         if(sum==0){
             break;
         }
         if(sum&1){
             printf("Collection #%d:/nCan't be divided./n/n",c);
             continue;
         }
         sum>>=1;
         memset(dp,0,sizeof(dp));
         dp[0]=1;
         int pos;
         for(i=1;i< =6;++i){
             for(j=sum;j>=0;--j){
                 if(dp[j]==0){
                     continue;
                 }
                if(dp[j+i]==1){     //就是这里...
                     continue;
                 }

                 pos=j;
                 for(k=0;k< mar[i];++k){
                     pos+=i;
                     if(pos>sum){
                         break;
                     }
                     dp[pos]=1;
                 }
             }
         }
         printf("Collection #%d:/n",c);
         if(dp[sum]==1){
             printf("Can be divided./n");
         }
         else{
             printf("Can't be divided./n");
         }
         printf("/n");
     }

     return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值