将6种价值不同,数量不同的石头,分成两组价值相同,问能否可分。
很容易想到是多重背包。
但是以哪个为容量是关键,我是以价值为容量,超时了。
不过这边有一个可以优化的地方。
for(int i=1;i<=6;i++)
{
num[i]=(num[i]*i)%60/i;
sumvalue+=num[i]*i;
}
mod最小公倍数60,只处理超过最小公倍数部分。其余的不处理。具体为何还在想。
#include<iostream>
#include<cstring>
using namespace std;
int dp[211111];
int main()
{
int num[7];
int Case=1;
while(cin>>num[1]>>num[2]>>num[3]>>num[4]>>num[5]>>num[6],num[1]||num[2]||num[3]||num[4]||num[5]||num[6])
{
memset(dp,0,sizeof(dp));
dp[0]=1;
int sumvalue=0;
for(int i=1;i<=6;i++)
{
num[i]=(num[i]*i)%60/i;
sumvalue+=num[i]*i;
}
for(int i=1;i<=6;i++)
{
if(num[i]==0)
continue;
int sum=num[i];
int k=1;
int mid;
while(k<sum)
{
mid=k*i;
for(int v=sumvalue;v>=mid;v--)
dp[v]+=dp[v-mid];
sum-=k;
k<<=1;
}
mid=sum*i;
for(int v=sumvalue;v>=mid;v--)
dp[v]+=dp[v-mid];
}
cout<<"Collection #"<<Case++<<":"<<endl;
if(dp[sumvalue/2]&&!(sumvalue&1))
cout<<"Can be divided."<<endl;
else
cout<<"Can't be divided."<<endl;
cout<<endl;
}
}