【多重背包模板】poj 1014

#include <iostream>
#include <stdio.h>
#include <cstring>
#define INF 100000000 
using namespace std;
int f[240005];  //f[j]相当于f[i][j]: 考虑1...i个物品,恰好放到容量为j,所能达到的最大价值
int v; //背包容量
void complete_pack(int *dp, int c, int w) 
{ 
    for(int i = c; i <= v; i++) 
        dp[i] = max(dp[i], dp[i - c] + w); 
} 
void zeroone_pack(int *dp, int c, int w) 
{ 
    for(int i = v; i >= c; i--) 
        dp[i] = max(dp[i], dp[i - c] + w); 
} 
 
void mutiple_pack(int *dp, int c, int w, int m) 
{  
    if(c * m >= v)
    { 
        complete_pack(dp, c, w); 
        return; 
    }
    int k = 1; 
    while(k < m) 
    { 
        zeroone_pack(dp, k * c, k * w); 
        m = m - k; 
        k = 2 * k; 
    } 
    zeroone_pack(dp, c * m, w * m); 
} 
int main() 
{ 
    //freopen("in.txt","r",stdin); 
    int sum, i, c[7], w[7], m[7],cas = 0; 
    while(scanf("%d%d%d%d%d%d",&m[1],&m[2],&m[3],&m[4],&m[5],&m[6]))
    { 
        if(m[1]==0 && m[2]==0 && m[3]==0 && m[4]==0 && m[5]==0 && m[6]==0) 
        break; 
        sum = 0; 
        for(i = 1; i <= 6; i++)
        { 
            c[i] = w[i] = i; 
            sum += c[i] * m[i]; 
        } 
        printf("Collection #%d:\n", ++cas); 
        if(sum & 1)
            puts("Can't be divided.\n"); 
        else
        { 
            sum /= 2; 
            v = sum;
            for(i = 1; i <= sum; i++) 
                  f[i] = -INF; 
            f[0] = 0; 
            for(i = 1; i <= 6; i++) 
                  mutiple_pack(f, c[i], w[i], m[i]); 
            if(f[v] < 0)
                puts("Can't be divided.\n"); 
            else
                puts("Can be divided.\n"); 
        } 
    } 
    return 0; 
}

 

posted @ 2014-10-10 10:40  balfish  阅读(144)  评论(0编辑  收藏  举报