hdu3591 The trouble of Xiaoqian(多重背包 + 完全背包)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>

 

using namespace std;

#define MAXN 105
#define MAXM 20005
#define INF 9999999

const int sum = 20000;
int weight[MAXN], num[MAXN];
int f1[MAXM], f2[MAXM];

inline int getMin(int a, int b)
{
    return a < b ? a : b;
}
void ZeroOnePack(int *f, int w, int v)
{
    for(int j = sum; j >= w; j--)
    {
        f[j] = getMin(f[j], f[j - w] + v);
    }
}
void CompletePack(int *f, int w, int v)
{
    for(int j = w; j <= sum; j++)
    {
        f[j] = getMin(f[j], f[j - w] + v);
    }
}
void MultiplePack(int *f, int amount, int w, int v)
{
    if(amount * w >= sum)
    {
        CompletePack(f, w, v);
        return;
    }
    int k = 1;
    while(k < amount)
    {
        ZeroOnePack(f, k * w, k * v);
        amount -= k;
        k <<= 1;
    }
    ZeroOnePack(f, amount * w, amount * v);
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("indata.txt", "r", stdin);
#endif
    int n, t, cas = 1;
    while(scanf("%d %d", &n, &t), n + t)
    {
        int i;
        for(i = 1; i <= n; i++) scanf("%d", &weight[i]);
        for(i = 1; i <= n; i++) scanf("%d", &num[i]);
     /*   for(i = 1; i <= sum; i++)
        {
            f1[i] = f2[i] = INF;
        }*/
        fill(f1 + 1, f1 + sum + 1, INF);
        fill(f2 + 1, f2 + sum + 1, INF);
        f1[0] = f2[0] = 0;
        for(i = 1; i <= n; i++) CompletePack(f2, weight[i], 1);
        for(i = 1; i <= n; i++) MultiplePack(f1, num[i], weight[i], 1);
        int minNum = INF;
        for(i = t; i <= sum; i++)
        {
            minNum = getMin(minNum, f1[i] + f2[i - t]);
        }
   //       printf("%d %d\n", f1[t], f2[i - t]);
        if(minNum < INF) printf("Case %d: %d\n", cas++, minNum);
        else printf("Case %d: -1\n", cas++);
    }
    return 0;
}

posted @ 2010-10-19 19:24  菜到不得鸟  阅读(153)  评论(0)    收藏  举报