百度之星资格赛 1003 度度熊与邪恶大魔王(二维dp)
分析
挺好的一道题
dp[i][j]表示打败i颗血j防御力的怪兽需要的最少宝石数
然后就好了,复杂度\(O(n+m*1000*10)\)
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define F(i,a,b) for(int i=a;i<=b;++i)
#define R(i,a,b) for(int i=a;i<b;++i)
#define mem(a,b) memset(a,b,sizeof(a))
int n,m;
int a[100100],b[100100],c[1010],d[1010];
ll f[1010][22];
const ll inf = 1e9;
void init()
{
F(i,0,1000)F(j,0,10) f[i][j]=1e9;
F(k,1,m)
{
if(d[k]==0) continue;
for(int j=0;j<d[k]&&j<=10;++j)
{
int x=d[k]-j;
for(int i=1;i<=x;++i) f[i][j]=min(f[i][j],(ll)c[k]);
for(int i=x+1;i<=1000;++i) f[i][j]=min(f[i][j],f[i-x][j]+c[k]);
}
}
}
int main()
{
while(scanf("%d %d",&n,&m)!=EOF)
{
F(i,1,n) scanf("%d %d",a+i,b+i);
F(i,1,m) scanf("%d %d",c+i,d+i);
init();
ll ans=0;
F(i,1,n)
{
if(f[a[i]][b[i]]==inf) { ans=-1;break; }
ans+=f[a[i]][b[i]];
}
printf("%I64d\n",ans );
}
return 0;
}
一直地一直地往前走