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;
}
浙公网安备 33010602011771号