FSN (dp)

来源:互联网 发布:nginx rtmp下载 编辑:程序博客网 时间:2024/06/15 09:54

FSN(fsn)

8.31

思路:
这是一道简单DP 题,两句话题解。
1. 完全背包打表,可以得到DP[i][j],i,j 表示生命值为i的龙牙兵防御力为j 时所需的宝石数。
2. 再跑一遍01 背包f[i][j],计算卫除掉前i个士兵,卫宫剩余血量为j,最少使用多少个宝石
3. 最后答案就是 min f[n][i]

#include <cstdio>#include <cstring>#include <algorithm>#include <iostream>#define N 3005#define LL long long#define del(a,b) memset(a,b,sizeof(a))using namespace std;const LL inf = 5000000000ll;int n, m, w, x, y;int g[N], dp[1005];LL f[N][2005];struct sde{    int l, f, t, cost;}sd[N];bool cmp(sde aa, sde bb){    return aa.f < bb.f;}void get_dp(int f){//一维存,for防御力    del(dp, 127);    dp[0] = 0;    for(int i=1; i<=1000; i++){        for(int j=0; j<i; j++)            dp[i] = min(dp[i], dp[j]+g[i-j+f]);    }}int main(){    freopen ("fsn.in", "r", stdin);    freopen ("fsn.out", "w", stdout);    scanf("%d%d%d", &n, &m, &w);    del(g, 127);    for(int i=1; i<=n; i++)        scanf("%d%d%d", &sd[i].l, &sd[i].f, &sd[i].t);    for(int i=1; i<=m; i++){        scanf("%d%d", &x, &y);        g[y] = min(g[y], x);    }//法术攻击产生y的伤害,最少需要x个宝石     for(int i=1000; i; i--)        g[i] = min(g[i], g[i+1]);//消除不优的法术     sort(sd+1, sd+n+1, cmp);    int last = -1;    for(int i=1; i<=n; i++){        if(sd[i].f != last){            last = sd[i].f;            get_dp(last);        }        sd[i].cost = dp[sd[i].l];    }    del(f, 127);    for(int i=0; i<=w; i++) f[0][i] = 0;//除掉前i个士兵,剩余血量为j,最少使用多少个宝石     for(int i=0; i<n; i++){        for(int j=0; j<=w; j++){            f[i+1][j] = min(f[i+1][j], f[i][j]+sd[i+1].cost);            if(j - sd[i+1].t >= 0)            f[i+1][j-sd[i+1].t] = min(f[i+1][j-sd[i+1].t], f[i][j]);        }    }    LL ans = inf;    for(int i=0; i<=w; i++) ans = min(ans, (LL)f[n][i]);    cout << ans;    return 0;}
原创粉丝点击