hdu6082-度度熊与邪恶大魔王

来源:互联网 发布:淘宝店铺换身份证 编辑:程序博客网 时间:2024/06/10 04:45

 题意: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 longusing 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;}