您的位置:首页 > 其它

HDU 3033 I love sneakers! (分组背包变形)

2013-03-20 00:12 477 查看
题目大意:xx去买鞋,有k种牌子,然后给出n双鞋,每双鞋有它属于的牌子、价格、收藏价值。xx认为他不差钱,要求每种鞋子买一双。但实际上他只有m毛钱,问能否买到符合xx要求的鞋,能找到的话输出最大的收藏价值总和。

分组背包的变形,每种牌子要求至少选一个,这与分组背包的每组最多选一个不一样,但背包的思想都是一样的。。。

就是状态转移的时候可以加上从上一组转移(选择1个)与本组转移(大于1个),还有注意枚举物品和枚举体积的顺序~~

设dp[i][j]表示前i组填到容量j的最大价值,

则方程为:dp[i][j] = max(dp[i][j],dp[i-1][j-price[i][k]] + value[i][k],dp[i][j-price[[i][k]] + value[i][k])

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MID(x,y) ((x+y)>>1)
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;

typedef long long LL;
const int sup = 0x7fffffff;
const int inf = -0x7fffffff;

struct shoes{
int price;
int value;
};
vector  s[11];

int f[15][10100];
int N, M, K;

int main(){
while(scanf("%d %d %d", &N, &M, &K) != EOF){
for (int i = 0; i < 11; i ++)
s[i].clear();
for (int i = 1; i <= N; i ++){
int tmp_brand, tmp_price, tmp_value;
scanf("%d %d %d", &tmp_brand, &tmp_price, &tmp_value);
shoes tmp;
tmp.price = tmp_price;
tmp.value = tmp_value;
s[tmp_brand].push_back(tmp);
}
mem(f, -1);
f[0][0] = 0;
for (int k = 1; k <= K; k ++)
for (int j = 0; j < (int)s[k].size(); j ++)
for (int v = M; v >= 0; v --){
if (v-s[k][j].price >= 0 && f[k][v-s[k][j].price] != -1){
f[k][v] = max(f[k][v], f[k][v-s[k][j].price]+s[k][j].value);
}
if (v-s[k][j].price >= 0 && f[k-1][v-s[k][j].price] != -1){
f[k][v] = max(f[k][v], f[k-1][v-s[k][j].price]+s[k][j].value);
}
}
int res = -1;
for (int v = 0; v <= M; v ++)
if (f[K][v] > res)
res = f[K][v];
if (res >= 0)
printf("%d\n", res);
else
printf("Impossible\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: