题目链接:http://poj.org/problem?id=1014
题目大意:告诉价值为1、2、3、4、5、6的物品各有几件,判断两人能否平分。
题目分析:方法很多,比如二进制多重背包、抽屉原理、dfs(需要预处理),不过我还是暂时没有考虑优化的问题,代码大概要跑60ms左右。注意剪枝和输出格式。
代码参考:
#include<cstdio>
#include<cstring>
char dp[60001];//实际上是bool型,判断能否放满i价值的物品
int mar[7];
int main()
{
int c = 0;//测试数据组数
while(++c)
{
int i, j, k, pos, sum = 0;
for(i=1; i<=6; ++i)
{
scanf("%d", &mar[i]);//为每种价值的物品数量
sum += mar[i]*i;//sum为总价值
}
if(sum == 0) break;//如果输入的都是“0”的话就退出
//剪枝
if(sum & 1)//如果总数不是偶数的话肯定无法平均分配
{
printf("Collection #%d:\nCan't be divided.\n\n", c);
continue;//以下步骤不再进行
}
sum >>= 1;;//看一半的价值能否放满一半的背包
memset(dp, 0, sizeof(dp));
dp[0] = 1;//什么都不放时背包里总价值为0, 因此此状态能达到
for(i=6; i>0; --i)//枚举六种价值的物品
{
for(j=sum; j>=0; --j)//枚举能否放满j价值的物品
{//如果放满j价值的物品的状态无法达到,或者达到了能放满j+i价值的物品,则不能继续往下推
if(dp[j] == 0 || dp[j+i] == 1) continue;
pos = j;
for(k=0; k<mar[i]; ++k)//枚举每种价值的物品数量
{
pos += i;//每放入一件i价值的物品
if(pos > sum) break;//如果已经超过一半的价值了,则退出
dp[pos] = 1;//此状态能达到
}
}
}//输出答案,注意格式
printf("Collection #%d:\n", c);
if(dp[sum] == 1) puts("Can be divided.\n");
else puts("Can't be divided.\n");
}
return 0;
}
ps:测试数据:
输入:
1 0 1 2 0 0
1 0 0 0 1 1
2 0 0 3 0 0
1 1 1 1 1 1
0 6999 0 6001 0 7000
0 0 0 0 4 5
3333 3333 3333 3333 3333 3333
0 0 0 1 0 2
1 2 3 4 5 6
0 0 0 0 4 5
0 0 2 3 0 0
0 0 0 2 2 1
0 0 0 1 2 2
0 1 2 3 4 5
6 5 4 3 2 1
0 0 5 0 3 0
0 3 0 0 0 1
0 2 0 1 0 0
1 1 1 0 0 0
3334 3334 3333 3333 3333 3333
0 1 1 1 1 1
0 0 0 0 6 5
0 0 0 3 0 2
0 0 1 3 3 4
0 0 0 1 4 6
0 0 0 1 4 5
0 0 0 0 0 0
答案:
Collection #1:
Can't be divided.
Collection #2:
Can be divided.
Collection #3:
Can't be divided.
Collection #4:
Can't be divided.
Collection #5:
Can't be divided.
Collection #6:
Can't be divided.
Collection #7:
Can't be divided.
Collection #8:
Can't be divided.
Collection #9:
Can't be divided.
Collection #10:
Can't be divided.
Collection #11:
Can't be divided.
Collection #12:
Can't be divided.
Collection #13:
Can't be divided.
Collection #14:
Can be divided.
Collection #15:
Can be divided.
Collection #16:
Can be divided.
Collection #17:
Can be divided.
Collection #18:
Can be divided.
Collection #19:
Can be divided.
Collection #20:
Can be divided.
Collection #21:
Can be divided.
Collection #22:
Can be divided.
Collection #23:
Can be divided.
Collection #24:
Can be divided.
Collection #25:
Can be divided.
Collection #26:
Can be divided.