思路:dp[ i ][ j ]:打败生命值为 i ,防御力为 j 的怪兽最少所需晶石数;枚举生命值,防御力 dp[ i ][ j ]=min(dp[ i ][ j ],dp[ i-lost ][ j ]+k);lost:失去的生命值;
代码:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define ll long long #define inf 1000000000000 const int N=100100; ll n,m; ll a[N],b[N],k[N],p[N]; ll dp[1010][15]; int main() { while(scanf("%d%d",&n,&m)!=EOF) { memset(dp,0,sizeof(dp)); memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); ll def=0,att=0; for(int i=1;i<=n;i++) { scanf("%I64d%I64d",&a[i],&b[i]); def=max(def,b[i]); } for(int i=1;i<=m;i++) { scanf("%I64d%I64d",&k[i],&p[i]); att=max(att,p[i]); } if(att<=def) //<= { printf("-1\n"); continue; } ll ans=0; for(int i=1;i<=1000;i++) //dp; { for(int j=0;j<=10;j++) { dp[i][j]=inf; for(int l=1;l<=m;l++) { if(p[l]<=j) continue; int lost=p[l]-j; if(lost>=i) dp[i][j]=min(dp[i][j],k[l]); else dp[i][j]=min(dp[i][j],dp[i-lost][j]+k[l]); } } } for(int i=1;i<=n;i++) ans+=dp[a[i]][b[i]]; printf("%I64d\n",ans); } return 0; }
