首页 > 代码库 > 完全背包,打表。
完全背包,打表。
2017-08-06 15:02:50 | Accepted | 1003 | 187 MS | 2168 K | G++ | redips |
对背包有了进一步的认识
-------------------------------------------------------------------
题目描述:
度度熊为了拯救可爱的公主,于是与邪恶大魔王战斗起来。
邪恶大魔王的麾下有n个怪兽,每个怪兽有a[i]的生命值,以及b[i]的防御力。
度度熊一共拥有m种攻击方式,第i种攻击方式,需要消耗k[i]的晶石,造成p[i]点伤害。
当然,如果度度熊使用第i个技能打在第j个怪兽上面的话,会使得第j个怪兽的生命值减少p[i]-b[j],当然如果伤害小于防御,那么攻击就不会奏效。
如果怪兽的生命值降为0或以下,那么怪兽就会被消灭。
当然每个技能都可以使用无限次。
请问度度熊最少携带多少晶石,就可以消灭所有的怪兽。
输入:
第一行两个整数n,m,表示有n个怪兽,m种技能。
接下来n行,每行两个整数,a[i],b[i],分别表示怪兽的生命值和防御力。
再接下来m行,每行两个整数k[i]和p[i],分别表示技能的消耗晶石数目和技能的伤害值。
数据范围:
1<=n<=100000
1<=m<=1000
1<=a[i]<=1000
0<=b[i]<=10
0<=k[i]<=100000
0<=p[i]<=1000
----------------------------------------------------------------------------------------
注意a只有1k,b只有10,而n为100000,所以需要打表。
#include <set> #include <map> #include <stack> #include <queue> #include <cmath> #include <vector> #include <string> #include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> #define MAX(a,b) ((a)>=(b)?(a):(b)) #define MIN(a,b) ((a)<=(b)?(a):(b)) #define OO 0x0fffffff typedef long long LL; using namespace std; const int N = 100100; const int M = 1024; int A[N],B[N]; int K[M],P[M]; int table[16][M]; int dp[M]; int main(){ int n,m; int a,b; while(scanf("%d%d",&n,&m)!=EOF){ for(int i=0;i<n;i++) scanf("%d%d",A+i,B+i); for(int i=0;i<m;i++) scanf("%d%d",K+i,P+i); memset(table,127,sizeof(table)); for(int defend=0;defend<=10;defend++){ int *dp = table[defend]; dp[0] = 0; for(int id=0;id<m;id++){ int value = http://www.mamicode.com/P[id] - defend; if(value<=0) continue; for(int life=0;life<=1000;life++){ int base = ((life-value)>=0)?(dp[life-value]):0; dp[life] = MIN(dp[life],base+K[id]); } } } LL ans = 0; bool flag = true; for(int i=0;i<n;i++) { int tmp = table[B[i]][A[i]]; if(tmp==2139062143) {flag=false;break;} ans += tmp; } if(flag) printf("%lld\n",ans); else puts("-1"); } return 0; }
完全背包,打表。
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。