[HDOJ6082] 度度熊与邪恶大魔王(枚举,完全背包)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6082

枚举所有怪兽可能的生命值和防御值,以此为代价,对魔法值和伤害值做完全背包,每次求出击杀怪物的最小花费,求答案的时候把各种组合的最小花费加起来即可。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long LL;
 5 const int maxn = 100100;
 6 const int maxm = 1010;
 7 const int maxp = 10010;
 8 const int maxa = 1010;
 9 const int maxb = 11;
10 const LL inf = (1LL << 60);
11 int n, m;
12 int a[maxn], b[maxn], k[maxm], p[maxm];
13 LL f[maxa][maxb];
14 
15 signed main() {
16     // freopen("in", "r", stdin);
17     while(~scanf("%d %d",&n,&m)) {
18         for(int i = 0; i < maxa; i++) {
19             for(int j = 0; j < maxb; j++) {
20                 f[i][j] = inf;
21             }
22         }
23         for(int i = 0; i < maxb; ++i) f[0][i] = 0;
24         int ha = -1, hb = -1;
25         for(int i = 1; i <= n; i++) {
26             scanf("%d%d",&a[i], &b[i]);
27             ha = max(ha, a[i]);
28             hb = max(hb, b[i]);
29         }
30         for(int i = 1; i <= m; i++) scanf("%d%d",&k[i], &p[i]);
31 
32         for(int i = 1; i <= ha; i++) {
33             for(int j = 0; j <= hb; j++) {
34                 for(int x = 1; x <= m; x++) {
35                     if(j >= p[x]) continue;
36                     if(i + j - p[x] > 0) f[i][j] = min(f[i][j], f[i+j-p[x]][j] + k[x]);
37                     else f[i][j] = min(f[i][j], f[0][j] + k[x]);
38                 }
39             }
40         }
41         LL ret = 0;
42         bool flag = 0;
43         for(int i = 1; i <= n; i++) {
44             if(f[a[i]][b[i]] == inf) {
45                 flag = 1;
46                 break;
47             }
48             ret += f[a[i]][b[i]];
49         }
50         if(flag) puts("-1");
51         else printf("%I64d
", ret);
52     }
53     return 0;
54 }
原文地址:https://www.cnblogs.com/kirai/p/7347269.html