动态规划,是一种技巧而非算法。这道题网上有很多种解法,dfs的算法我是没有看懂,但是我觉得用动态规划就很简单。算法导论上给出了解决动态规划问题的基本策略,十分经典,但是在解决问题的时候,诸如此题,会涉及一些别的东西来对涉及的算法优化,这个时候,需要更多的知识。我是看了大神的解法之后才明白用二进制转多重背包为01背包再求解的,想想还真的不是一道难题。
#include
#include
#include
using namespace std;
int const maxn=300010;
int val[maxn], num[7], t;
int dp[maxn];
//将多重背包转化为01背包
void init(int n,int v)//傳入多重背包第i项的数量及价值
{
int i=0,tmp=0,x;
while(1)
{
x=1<n) break;
tmp+=x;
val[t++]=x*v;//建立的01背包中的各个物品val[t];
i++;
}
x=n-tmp;
if(x!=0) val[t++]=x*v;
}
int main()
{
int n=1;
while(1)
{
int sum=0;
memset(dp,0,sizeof(dp));
for(int i=1;i<=6;i++)
{
scanf("%d",&num[i]);
sum+=num[i]*i;
}
if(sum==0) break;
printf("Collection #%d:\n", n++);
if(sum%2==1)
{
printf("Can't be divided.\n\n");
continue;
}
int mid=sum/2;
t=0;
for(int i=1;i<=6;i++)
init(num[i],i);
//cout<=val[i];j--)
{
if(dp[j-val[i]]+val[i]>dp[j])
dp[j]=dp[j-val[i]]+val[i];
}
if(dp[mid] == mid)
printf("Can be divided.\n\n");
else
printf("Can't be divided.\n\n");
}
return 0;
}