dp…
因为防御力的范围很小,最大才是10,所以就可以枚举防御力,从1到10,然后如果防御大于等于造成的伤害的话就直接continue…如果防御小于伤害的话就砍,然后如果用这一个技能就把它砍死了,那么这就是使用晶石最少的技能,否则就通过前面的dp值推出当前的dp值(dp[i][j]=dp[i-mul][j]+con[k];)
dp[i][j]表示防御力为j,打出i点伤害所需要的最少的晶石
#include <iostream>
#include <cstring>
#include <cstdio>
#define MAX 0x3f3f3f3f
using namespace std;
int n,m;
bool flag;
long long mon[120000],skl[120000],con[1200],ht[1200],dp[1200][22],tot,maxn;
int main()
{
while(cin>>n>>m)
{
flag=false,tot=0,maxn=-123456789;
memset(dp,MAX,sizeof(dp));
for(int i=0;i<n;i++)
cin>>mon[i]>>skl[i];
for(int i=0;i<m;i++)
{
cin>>con[i]>>ht[i];
if(ht[i]>maxn)
maxn=ht[i];
}
for(int i=0;i<n;i++)
if(skl[i]>=maxn)
{
flag=true;
break;
}
if(flag)
{
cout<<"-1"<<endl;
continue;
}
for(int i=0;i<=12;i++)
dp[0][i]=0;
//cout<<dp[0][1];
for(int k=0;k<m;k++)
for(int j=0;j<=10;j++)
for(int i=0;i<=1000;i++)
{
long long mul=ht[k]-j;
if(mul<=0) continue;
if(mul>=i)
dp[i][j]=min(dp[i][j],con[k]);
else if(dp[i][j]>dp[i-mul][j]+con[k])
dp[i][j]=dp[i-mul][j]+con[k];
}
for(int i=0;i<n;i++)
tot+=dp[mon[i]][skl[i]];
cout<<tot<<endl;
}
return 0;
}