题意:n个怪兽,每个怪兽有a[i]的生命值和b[i]的防御力。
主角有m个技能,每个 技能需要消耗k[i]的晶石和造成p[i]的伤害。
问:要杀掉所有的怪兽,所花费的最少的晶石是多少。
分析:相同 的生命值和相同防御力的怪兽消耗的晶石是一样多的,所以怪兽最多算 1000*10个。
相当于一个完全背包,对于一个生命值为j,防御力为i的怪兽,杀掉他最少的花费是多少。
所以 是先要枚举生命值和防御力 ,再用m个技能去匹配。
模板完全 背包。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define siz 100005
#define LL long long
using namespace std;
int n,m;
int ga[siz],gb[siz];
int gk[siz],gp[siz];
LL dp[11][1005];
int MAXA,MAXB,MAXP,MAXK;
void _Init(){
for(int i=0;i<11;i++){
for(int j=0;j<1005;j++){
dp[i][j] = 1LL*siz*siz;
}
}
}
void solve(){
int flag = 1;
for(int i=0;i<=10;i++){
for(int j=1;j<=1000;j++){
for(int k=1;k<=m;k++){
if(gp[k]<=i) continue;
LL tem = gp[k] - i;
if(tem>=j){
dp[i][j] = min(dp[i][j],1LL*gk[k]);
}
else{
dp[i][j] = min(dp[i][j],dp[i][j-tem]+gk[k]);
}
}
}
}
LL ans = 0;
for(int i=1;i<=n;i++){
ans += dp[gb[i]][ga[i]];
}
printf("%lld\n",ans);
}
int main()
{
while(~scanf("%d%d",&n,&m)){
int x,y;
MAXA = MAXB = MAXP = MAXK = 0;
for(int i=1;i<=n;i++){
scanf("%d%d",&x,&y);
ga[i] = x;
MAXA = max(MAXA,x);
gb[i] = y;
MAXB = max(MAXB,y);
}
for(int i=1;i<=m;i++){
scanf("%d%d",&gk[i],&gp[i]);
MAXK = max(MAXK,gk[i]);
MAXP = max(MAXP,gp[i]);
}
if(MAXP<=MAXB){
puts("-1");
continue;
}
//memset(dp,0,sizeof(dp));
_Init();
solve();
}
return 0;
}