Dividing HDU - 1059(多重背包可行性问题+二进制优化)

题意:现有面值为1、2、3、4、5、6的硬币若干枚,现在需要知道能不能将这些硬币分成等额的两堆。

AC代码:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn=1e5+6;
int dp[maxn],num[10],v[maxn];
int main() {
	int kase=0;
    while(cin>>num[1]>>num[2]>>num[3]>>num[4]>>num[5]>>num[6]){
    	memset(dp,0,sizeof(dp));
    	if(!num[1]&&!num[2]&&!num[3]&&!num[4]&&!num[5]&&!num[6])break;
    	printf("Collection #%d:\n",++kase);
    	int sum=num[1]*1+num[2]*2+num[3]*3+num[4]*4+num[5]*5+num[6]*6;
    	if(sum%2){
    		cout<<"Can't be divided."<<endl<<endl;;
    		continue;
		}
		sum=sum/2;
		int cnt=0;
		for(int i=1;i<=6;i++){
			for(int j=1;j<=num[i];j=j*2){
				v[++cnt]=j*i;
				num[i]-=j;
			}
			if(num[i]>0)v[++cnt]=num[i]*i;
		}
		for(int i=1;i<=cnt;i++)
			for(int j=sum;j>=v[i];j--)
			dp[j]=max(dp[j],dp[j-v[i]]+v[i]);
		if(dp[sum]==sum)cout<<"Can be divided."<<endl<<endl;
		else cout<<"Can't be divided."<<endl<<endl;;	
	}
}

猜你喜欢

转载自blog.csdn.net/Alanrookie/article/details/107469997