度度熊为了拯救可爱的公主,于是与邪恶大魔王战斗起来。
邪恶大魔王的麾下有n个怪兽,每个怪兽有a[i]的生命值,以及b[i]的防御力。
度度熊一共拥有m种攻击方式,第i种攻击方式,需要消耗k[i]的晶石,造成p[i]点伤害。
当然,如果度度熊使用第i个技能打在第j个怪兽上面的话,会使得第j个怪兽的生命值减少p[i]-b[j],当然如果伤害小于防御,那么攻击就不会奏效。
如果怪兽的生命值降为0或以下,那么怪兽就会被消灭。
当然每个技能都可以使用无限次。
请问度度熊最少携带多少晶石,就可以消灭所有的怪兽。
Input本题包含若干组测试数据。
第一行两个整数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
Output对于每组测试数据,输出最小的晶石消耗数量,如果不能击败所有的怪兽,输出-1
Sample Input 1 2 3 5 7 10 6 8 1 2 3 5 10 7 8 6 Sample Output 6 18DP思路去做,构造状态方程,dp[i][j]为攻击护甲为j,能打出血量为i的最小消耗晶石值
因为所给数据的范围中,只有b[i](护甲值)最小,所以我们可以利用这一点去遍历
当技能p[i]<=当前护甲值,说明打不出伤害值,我们就把他舍弃,不用管它;
当技能p[i]>当前护甲值,伤害值hurt则为p[i]-当前护甲值
如果hurt>当前生命值,则只需要这一个技能就能够打到怪兽,并且让dp记录消耗晶石最小的当前技能
如果hurt<当前生命值,,那么dp[][]记录最小的未打出这一次伤害值的前一次dp[][]值+此次技能消耗的晶石
k[u]为第u个技能消耗的晶石值;
eg:还是根据最上方对dp数组的定义,如果hurt>hp,dp[i][j]=min{k[u]},如果hurt<hp,dp[i][j]=min{dp[i-hurt][j]+k[u]};
#include <iostream> #include <cstring> #include <stack> #include <cstdio> #include <cmath> #include <queue> #include <algorithm> #include <vector> #include <set> #include <map> typedef long long LL; const double eps=1e-8; const double PI=acos(-1.0); using namespace std; LL dp[1005][15]; LL a[100005],b[100005]; LL p[1005],k[1005]; LL max(LL a,LL b) { return a>b?a:b; } LL min(LL a,LL b) { return a<b?a:b; } int main() { int n,m; while(scanf("%d%d",&n,&m)!=EOF) { LL mdef=0,mhp=0;//最大护甲值,最大生命值 memset(dp,0,sizeof(dp)); for(int i=0; i<n; i++) { scanf("%I64d%I64d",&a[i],&b[i]); mhp=max(mhp,a[i]); mdef=max(mdef,b[i]); } LL mhit=0;//技能的最大伤害值 for(int i=0; i<m; i++) { scanf("%I64d%I64d",&k[i],&p[i]); mhit=max(mhit,p[i]); } if(mhit<=mdef) { printf("-1\n"); continue; } for(int i=0; i<=10; i++)//护甲值0-10遍历 { for(int j=1; j<=mhp; j++)// { dp[j][i]=1e18; for(int u=0; u<m; u++) { int hurt=p[u]-i; if(hurt>=j) dp[j][i]=min(dp[j][i],k[u]); else if(hurt>0) dp[j][i]=min(dp[j][i],dp[j-hurt][i]+k[u]); } } } long long ans=0; for(int i=0;i<n;i++) ans+=dp[a[i]][b[i]];//ans记录所有出现的i生命值j护甲值被消灭所需要的晶石数 printf("%I64d\n",ans); } return 0; }