题目链接: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 }