bitset做法
#include <bits/stdc++.h> #define PI acos(-1.0) #define mem(a,b) memset((a),b,sizeof(a)) #define TS printf("!!!\n") #define pb push_back //std::ios::sync_with_stdio(false); using namespace std; //priority_queue<int,vector<int>,greater<int>> que; const double EPS = 1.0e-8; typedef pair<int, int> pairint; typedef long long ll; typedef unsigned long long ull; const int maxn = 2e5 + 100; const int maxm = 300; //next_permutation //priority_queue<int, vector<int>, greater<int>> que; int num[10]; bitset<120005>f; int main() { //freopen("bonuses.in", "r", stdin); //freopen("out.txt", "w", stdout); int t = 0; int sum = 0; //cin >> t; 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])) { t++; cout<<"Collection #"<<t<<":"<<endl; sum = 0; f.reset(); f[0] = 1; for (int i = 1; i <= 6; i++) { sum += num[i] * i; } if (sum % 2) { cout << "Can't be divided." << endl; } else { sum /= 2; for (int i = 1; i <= 6; i++) { int g = 1; int v = i; int tot = num[i]; while (tot) { f |= f << v; tot -= g; g = min(g * 2, tot); v = g * i; } } if (f[sum]) { cout << "Can be divided." << endl; } else { cout << "Can't be divided." << endl; } //for(int i=1;i<=sum;i++) //cout<<f[i]<<" "; //cout<<endl; } cout<<endl; } }
多重板子做法
//多重背包 //HDU 1059 //题意:价值分别为1,2,3,4,5,6的物品的个数分别为 a[1],a[2],````a[6] //问能不能分成两堆价值相等的 #include<stdio.h> #include<string.h> int a[7]; int f[120005]; int v,k; void ZeroOnePack(int cost,int weight)//cost 为费用, weight 为价值 { for(int i=v;i>=cost;i--) if(f[i-cost]+weight>f[i]) f[i]=f[i-cost]+weight; } void CompletePack(int cost,int weight) { for(int i=cost;i<=v;i++) if(f[i-cost]+weight>f[i]) f[i]=f[i-cost]+weight; } void MultiplePack(int cost ,int weight,int amount) { if(cost*amount>=v) CompletePack(cost,weight); else { for(int k=1;k<amount;) { ZeroOnePack(k*cost,k*weight); amount-=k; k<<=1; } ZeroOnePack(amount*cost,amount*weight); } } int main() { int tol; int iCase=0; while(1) { iCase++; tol=0; for(int i=1;i<7;i++) { scanf("%d",&a[i]); tol+=a[i]*i;//总价值数 } if(tol==0) break; if(tol%2==1) { printf("Collection #%d:\nCan't be divided.\n\n",iCase); continue; } else { v=tol/2; memset(f,0,sizeof(f)); for(int i=1;i<7;i++) MultiplePack(i,i,a[i]); if(f[v]==v) printf("Collection #%d:\nCan be divided.\n\n",iCase); else printf("Collection #%d:\nCan't be divided.\n\n",iCase); } } return 0; }