hdu 2159 FATE (水题,dp)

小记:1A,


思路:二维完全背包。看数据,本来以为需要三维dp的,后来想了一下,只要二维就可以解决了。

dp[i][j] 表示杀i个怪用了j点耐久度能获得的最大经验值

转移方程:

dp[i][j] = max(dp[i][j], dp[i-1][j - a[i].p] + a[i].v)  (a[i].p是杀第i种怪要用掉的耐久度,a[i].v是杀第i种怪能得到的经验)

初始化都是0

最后的结果就是

只要dp[i][j]大于需要升级的经验值,那么就可以升级,然后看用了多少耐久度,保留最大的那个即可。


因为每种怪都是无限个的,所以是个完全背包问题。


#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <map>
#include <set>
#include <vector>
#include <stack>
#include <algorithm>

using namespace std;

#define mst(a,b) memset(a,b,sizeof(a))
#define eps 10e-8

const int MAX_ = 110;
const int N = 100010;
const int INF = 0x7fffffff;


struct node {
    int v,p;
} a[MAX_];

int dp[MAX_][MAX_];

int main() {
    int n, m, k, s, ans, mmax;
    while(~scanf("%d%d%d%d",&n,&m,&k,&s)) {
        for(int i = 0; i < k; ++i) {
            scanf("%d%d",&a[i].v,&a[i].p);
        }
        mst(dp,0);
        ans = -1;
        for(int i = 0; i < k; ++i) {
            for(int j = 1; j <= s; ++j) {
                for(int r = 0; r <= m; ++r) {
                    if(r - a[i].p >= 0) {
                        dp[j][r] = max(dp[j][r], dp[j-1][r - a[i].p] + a[i].v);
                    }
                }
            }
        }
        for(int i = 1; i <= s; ++i) {
            for(int j = 0; j <= m; ++j) {
                if(dp[i][j] >= n) {
                    ans = max(ans,m - j);
                }
            }
        }

        printf("%d\n",ans);
    }
    return 0;
}


你可能感兴趣的:(hdu 2159 FATE (水题,dp))