度度熊与邪恶大魔王

来源:互联网 发布:基于代理模型的优化 编辑:程序博客网 时间:2024/04/29 11:18

虫洞传送门
刚开始想了很多种玄学的贪心。。。。。
正解:DP
n,m都不小,而且还有多组数据。。。。。。
但是 防御<=10,生命伤害都<=1000
那看来DP的状态中一定有防御了
令DP[i][j]为防御为i,打出>=j的伤害所需要的最少的晶石数
我们枚举技能
如果技能的伤害无法破防,那么这个技能略过
dmg=技能伤害-防御力
如果dmg>=j,那么DP[i][j] = min(DP[i][j],k[技能])
如果dmg< j , 那么此技能就要与其他技能打出合击技,与其他技能组合打出>=j的伤害
此时DP[i][j] = min(DP[i][j],DP[i][j-dmg]+k[技能])

#include <cstdio>#include <iostream>#include <cstring>#define ll long longusing namespace std;ll dp[21][2001];ll li[200001],f[200001];ll s[2001],k[2001];ll maxf,maxn;ll n,m;void work(){    maxf=0,maxn=0;     memset(dp,127,sizeof(dp));    for(ll i=1;i<=n;i++)     scanf("%lld%lld",&li[i],&f[i]),maxf=max(f[i],maxf);    for(ll i=1;i<=m;i++)     scanf("%lld%lld",&k[i],&s[i]),maxn=max(maxn,s[i]);    if(maxn<=maxf)     {        printf("-1\n");        return;     }    for(ll i=0;i<=10;i++)     for(ll j=1;j<=1000;j++)     {       for(ll l=1;l<=m;l++)       {        ll dmg=s[l]-i;        if(dmg<=0) continue;        if(dmg>=j)         dp[i][j]=min(dp[i][j],k[l]);        else         dp[i][j]=min(dp[i][j],dp[i][j-dmg]+k[l]);       }    }    ll ans=0;    for(ll i=1;i<=n;i++)    ans+=(dp[f[i]][li[i]]);    printf("%lld\n",ans);}int main(){    while(scanf("%lld%lld",&n,&m)!=EOF)     work();    return 0;}
原创粉丝点击