动态规划,是一种技巧而非算法。这道题网上有很多种解法,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; }