您的位置:首页 > 其它

hdu 1059 dp

2013-05-11 14:58 323 查看
题意是有值为1-6的东东,告诉你每个东东有多少个(个数为num[i]),问你能不能分成值相等的两份

在poj上面也有一样的题目,但是之前做的时候搜索到的题解用的(方法一:多重背包+二进制优化)||(方法二:dp),但是都写得比较难理解,所以一直没有搞懂,看了下面的dp终于明白了.

分析:

如果总数sum不是偶数,那么肯定不行

如果sum偶数,那么区total=sum/2,看dp[total]是否可达(可达为1).

初始时设置dp[1]-dp[total]都不可达(为0)

如果dp[l]可达,那么dp[l+k*i]也可达(k为东东的值,i<=num[i])

#include"stdio.h"
#include"string.h"
int dp[60011];//是否可以满足要求达到
int main()
{
int num[7];
int i,l,k;
int sum;
int total;
int Case=1;
while(scanf("%d",&num[1])!=-1)
{
sum=num[1];
for(i=2;i<=6;i++)	{scanf("%d",&num[i]);sum+=num[i]*i;}

if(sum==0)	break;
if(sum%2!=0)
{
printf("Collection #%d:\n",Case++);
printf("Can't be divided.\n\n");
continue;
}

total=sum/2;
for(l=1;l<=total;l++)	dp[l]=0;//初始化都不可达
dp[0]=1;//0显然可达
for(i=0;i<=6;i++)//主要理解这里面
{
for(l=total;l>=0;l--)
{
if(dp[l]==0)	continue;
for(k=1;k<=num[i]&&k*i+l<=total;k++)
{
if(dp[k*i+l])	break;
dp[k*i+l]=1;//如果dp[l]可达,添加一个物品也满足条件
}
}
}

if(dp[total])
{
printf("Collection #%d:\n",Case++);
printf("Can be divided.\n\n");
}
else
{
printf("Collection #%d:\n",Case++);
printf("Can't be divided.\n\n");
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: