-
大家都知道在dota游戏中,装备是对于英雄来说十分重要的要素。
英雄们不仅可以购买单个的装备,甚至某些特定的装备组合能够合成更强的装备。
为了简化问题,我们将每个装备对于英雄的功能抽象为一个整数:价值。同时,如上所说,一些特定的装备可以用来合成更强的装备,玩家会因此获得除原装备价值外额外的价值。
给定玩家现有的金钱数,每个装备的价格和其对应的价值,以及装备合成的信息。输出,其能获得的最大价值数。
注意:每件装备只能参与合成一件合成装备(即原装备参与合成后得到合成后的新装备,原装备消失),除非一次购买多个该种装备。
http://ac.jobdu.com/problem.php?pid=1494
题目描述:
-
输入:
-
输入包含多组测试数据,每组测试数据第一行为三个整数n,m,g(1<=n<=100),(0<=m<=100),(1<=g<=1000)。
分别表示存在的装备总数n,存在的装备合成关系数m,和英雄所有的金钱g。
接下去n行,每行两个整数(p,v)(1<=p<=100,1<=v<=100)分别表示该件装备的价格p,和其自身的价值v。
每组测试数据的最后为m行数据,每行由两部分组成。开头一个整数t(1<=t<=n),表示该组合成关系中需要t件装备,下去紧跟t件装备编号(按照装备在输入中的顺序从1到n编号),表示参与合成该装备的装备编号,最后一个数s(1<=s<=1000),代表这t件物品合成道具后获得的额外价值。
-
输出:
-
对于每组测试数据,输出一个整数,代表英雄可以获得的最大价值。
-
样例输入:
-
3 1 100 100 20 50 9 50 9 2 2 3 1 3 1 100 100 20 50 9 50 9 2 2 3 3
-
样例输出:
-
20 21
/* *这个题目是完全背包问题(物品可以有很多件) *最难的地方就是读懂题意,不会打dota的读了一个小时没懂。 */ #include <cstdio> #include <cctype> #include <string.h> int dp[1001]; struct E{ int p, v; }c[1001]; inline bool getint(int &x){ x = 0; int mute = 1; char c; while(!isdigit(c = getchar()) && c != '-') if(c == -1) return false; c == '-' ? mute = -1 : x = c - '0'; while(isdigit(c = getchar())) x = (x << 1) + (x << 3) + c - '0'; x *= mute; return true; } int main(){ int n, m, g, t, s, tmp, a, b; while(getint(n) && getint(m) && getint(g)){ //读入前n件物品的价格 + 价值 for(int i = 1; i <= n; i++){ getint(c[i].p); getint(c[i].v); } //后m件物品的价格 + 价值 for(int i = 1; i <= m; i++){ getint(t); a = b = 0; while(t--){ getint(tmp); a += c[tmp].p; b += c[tmp].v; } getint(s); c[n + i].p = a; c[n + i].v = b + s; } n += m; memset(dp, 0, sizeof(dp)); //注意完全背包中 j 是从 g - c[i].p 变化,要是0 - 1 背包的话变化该是从g - c[i].p变化, for(int i = 1; i <= n; i++){ for(int j = c[i].p; j <= g; j++) dp[j] = dp[j] > dp[j - c[i].p] + c[i].v ? dp[j] : dp[j - c[i].p] + c[i].v; } printf("%d\n", dp[g]); } return 0; }