度度熊与邪恶大魔王 DP | 完全背包
6 18
DP
根据输入的攻击力及耗费的晶石把任意生命力和血量的怪兽处理出来,之后O(1)查找每个怪兽消耗的晶石。时间1000*10*1000(也就7个零)
1 #include<iostream> 2 #include<stdio.h> 3 #include<math.h> 4 #include<algorithm> 5 #include<string.h> 6 using namespace std; 7 __int64 dp[1005][15]; 8 int p[1111], k[1111]; 9 int a[100000 + 5], b[100000 + 5]; 10 int main() 11 { 12 int n, m; 13 while (~scanf("%d%d", &n, &m)) 14 { 15 int i,j, u; 16 memset(dp, 111111, sizeof(dp));//初始化 17 dp[0][0] = 0; 18 int maxb = 0, maxp = 0; 19 for (i = 1; i <= n; i++) 20 { 21 scanf("%d%d", &a[i], &b[i]); 22 maxb = max(b[i], maxb); 23 } 24 for (i = 1; i <= m; i++) 25 { 26 scanf("%d%d", &k[i], &p[i]); 27 maxp = max(p[i], maxp); 28 } 29 //------------特判----------- 30 if (maxp <= maxb)//最大的攻击力小于等于最大的防御力即不能对此怪造成伤害。 31 { 32 printf("-1\n"); 33 continue; 34 } 35 //--------------------------- 36 //-------------血为i 防御力为j------------------ 37 __int64 t, x; 38 for (i = 1; i <= 1000; i++) 39 { 40 for (j = 0; j <= 10; j++) 41 { 42 x = t = dp[i][j]; 43 for (u = 1; u <= m; u++) 44 { 45 if (p[u] <= j) 46 continue; 47 if (p[u] - j >= i) 48 x = k[u]; 49 else 50 x = dp[i - p[u] + j][j] + k[u]; 51 t = min(x, t); 52 } 53 dp[i][j] = t; 54 } 55 } 56 //------------------------------------------------- 57 __int64 sum = 0; 58 for (i = 1; i <= n; i++) 59 { 60 sum += dp[a[i]][b[i]]; 61 } 62 cout << sum << endl; 63 } 64 }