hdu 3033 I love sneakers!(分组01背包)

题意:

 

Iserlohn 要买运动鞋,商店总共有n双运动鞋Iserlohn喜欢,他总共有V元钱,这些运动鞋分为k类,没类都有自己的编号id,单价p,对Iserlohn的价值v。Iserlohn想每一类运动鞋至少买一双,在不超过他所拥有的总金额前提下,使他得到的v最大。

状态设计:

                 如果没有品牌的分类,这个题就是经典的01背包问题;当然,这里有了品牌的分类,使用

           01背包自然是不行了;这就涉及到了加维。如何加维呢?加维的目的,是为了能够更好的表示

        状态,根据题意的要求状态的表示要求有二:A、每个品牌至少要有一件;B、钱的最大花费是

       有限制的;所以很容易我们就可以确定在一维的基础上加一维,用二维表示;

          f[kind][money]   (kind表示当前已经拥有的品牌种类数目,money 表示当前已经花费了的前

       的数目)。

      状态转移:

           根据我们的状态设计;

                 当前状态的来源有二:A、当前品牌数目的前提之下取最大的值;

                                             B、在比当前数目小的基础之上放一个另外品

                                牌的商品的最大值;

                 所以我们就很容易就设计出状态转移方程:

                      f[j][v]= max(f[j][v], f[j][v-cost]+value);

                      f[j][v]= max(f[j][v], f[j-1][v-cost]+value);

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

#define MAXN 10001
#define MAXM 11
#define INF -9999999

int f[MAXM][MAXN];

struct SNode
{
    int weight;
    int value;
};
SNode sneakers[MAXM][MAXN];
int num[MAXN];

inline int getMax(int a, int b) { return a > b ? a : b; }
bool solve(const int M, const int K)
{
    int i, j, n, k;
    for(i = 0; i <= K; i++)
        for(j = 0; j <= M; j++)
            f[i][j] = INF;
    f[0][0] = 0;
    // this one is not right, but the data...
    //  memset(f, 0, sizeof(f));
    i = 0;
    for(k = 1; k <= K; k++)
    {
        if(num[k]) i++; //number of brand
        for(n = 0; n < num[k]; n++)
        {
            int w = sneakers[k][n].weight;
            int v = sneakers[k][n].value;
            for(j = M; j >= w; j--)
            {
                f[i][j] = getMax(f[i][j], f[i][j - w] + v);
             //   if(i > 1)
                f[i][j] = getMax(f[i][j], f[i - 1][j - w] + v);
            }
        }
    }
    return i == K;
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("indata.txt", "r", stdin);
#endif
    int N, M, K;
    while(scanf("%d %d %d", &N, &M, &K) != EOF)
    {
        memset(num, 0, sizeof(num));
        int i;
        for(i = 1; i <= N; i++)
        {
            int a, b, c;
            scanf("%d %d %d", &a, &b, &c);
            sneakers[a][num[a]].weight = b;
            sneakers[a][num[a]++].value = c;
        }
     /*   for(i = 1; i <= K; i++)
        {
            for(int j = 0; j < num[i]; j++)
            {
                printf("(%d %d %d)\n", i, sneakers[i][j].weight, sneakers[i][j].value);
            }
            if(num[i]) printf("\n");
        }*/
        if(!solve(M, K)) printf("Impossible\n");
        else
        {
            int ans = INF;
            for(i = 0; i <= M; i++)
            {
                if(ans < f[K][i]) ans = f[K][i];
            }
            if(ans < 0) printf("Impossible\n");
            else printf("%d\n", ans);
        }
    }
    return 0;
}

posted @ 2010-10-22 11:09  菜到不得鸟  阅读(566)  评论(0)    收藏  举报