题目链接:HDOJ 1059
题目大意:有价值分别为1,2,3,4,5,6的六种marbles,每种都有一定的数量,求是否可以把它们按照一定的组合价值等分...
题解:首先,记录这些的总价值,如果他们的总值不是偶数,一定不能被等分,然后用多重背包加二进制判断它们是否能被等分。
代码:
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>//sort();
using namespace std;
#define debug 0
#define M(a) memset(a,0,sizeof(a))
#define Max(a,b) ((a>b)?a:b)
const int maxn = 120000 + 5;
int dp[maxn],w[105],t,sum;
void Do()
{
for(int i = 1;i < t;i++)
{
for(int j = sum;j >= w[i];j--)
{
dp[j] = Max(dp[j],dp[j - w[i]] + w[i]);
// printf("%d::%d\n",sum,dp[j]);
if(dp[j] == sum/2){
printf("Can be divided.\n\n");
return;
}
}
}
printf("Can't be divided.\n\n");
}
int main()
{
#if debug
freopen("in.txt","r",stdin);
#endif//debug
int a,k,caseNum = 0;
while(1)
{
caseNum++;
sum = 0;
t = 1;
for(int i = 1;i <= 6;i++)
{
scanf("%d",&a);
sum += a*i;
k = 1;
while(k <= a)
{
w[t++] = k * i;
a -= k;
k *= 2;
}
w[t++]=a*i;
}
if(!sum) break;
M(dp);
printf("Collection #%d:\n",caseNum);
if(sum % 2 != 0)
{
printf("Can't be divided.\n\n");
}
else
Do();
}
return 0;
}