题目链接:
题目思路:典型的背包问题,一开始的思路是将多重背包转变为01背包从而求解出相应的答案,最后发现这样的话会超时,那么我们就要想办法优化这个算法,所以我们采用了二进制的方法来优化多重背包。
优化的思路:
思路:这接对k进行1,2,4,8·····的分解,大于0的部分不要忘记,分解的时候注意V与W的重新分配。
代码:
#include<bits/stdc++.h> using namespace std; int v[500]; int n[10]; int dp[1000000]; int main() { fill(dp,dp+1000000,0); int sum=0; for(int i=1;i<=6;i++){ scanf("%d",&n[i]); sum+=n[i]*i; } int meng=sum/2; if(sum%2!=0) printf("Can't be divided.\n"); else{ int num=1; for(int i=1;i<=6;i++){ int k=1,tmp=n[i]; for(k=1;k<=tmp;k=k*2){//直接对n[i]进行分配,然后重新确定v[i]与w[i],因为这里v[i]与w[i]相同所以w[i]不作处理 v[num++]=i*k; tmp-=k; } if(tmp>0) v[num++]=i*tmp; } for(int i=1;i<=num-1;i++) for(int j=meng;j>=v[i];j--){ dp[j]=max(dp[j],dp[j-v[i]]+v[i]); } if(dp[meng]==meng) printf("Can be divided.\n"); else printf("Can't be divided.\n"); } return 0; }