Dividing

题目:Dividing

题解:这是一道多重背包。采用了二进制拆分。

#include 
using namespace std;
typedef long long ll;
const int N = 1e3+10;
const ll mod = 1e9+7;
const int inf = 0x7FFFFFFF;

int a[7];
int dp[1000000];



void solve(){
    
    int sum = 0;
    for(int i = 1;i <= 6;i++){
        sum += i*a[i];
    }
    if(sum%2){
        printf("Can't be divided.\n");
        return;
    }
    int n = sum/2;
    
    for(int i = 0;i <= n;i++){
        dp[i] = -inf;
    }
    dp[0] = 0;
    for(int i = 1;i <= 6;i++){
        int num = min(a[i],n/i);
        for(int k = 1;num > 0;k <<= 1){
            if(k > num) k = num;
            num -= k;
            for(int j = n;j >= i*k;j--){
                dp[j] = max(dp[j],dp[j-i*k]+i*k);
            }
        }
    }
    if(dp[n] == n){
        printf("Can be divided.\n");
    }else printf("Can't be divided.\n");
}
int main(){
    int cnt = 1;
    while(scanf("%d%d%d%d%d%d",&a[1],&a[2],&a[3],&a[4],&a[5],&a[6])&&a[1]+a[2]+a[3]+a[4]+a[5]+a[6]){
        printf("Collection #%d:\n",cnt++);
        solve();
        cout<

你可能感兴趣的:(HDU,多重背包)