HDU 2159 FATE(二維dp揹包)

這個題由於變量比較多。 所以容易搞複雜。 其實看明白了 還是一個揹包問題。


但是這個明顯就是 一種怪可以打很多個了。


有一個細節需要注意。被這個細節坑了一發。 那就是 當 它的 經驗超過n的時候 也是可以升級的。 比如 經驗需要3  有一種 可以得到經驗2 的怪。 那就必須殺兩個得到4個經驗


才能升級。 而我第一次寫的代碼就是 只判斷了 3的情況。 所以就錯了。我往後推了一步。因爲經驗最多就是20. 那我 直接得出 n----n+20之間的所有情況就好了


遞推公式比較好寫。 我用  d【i】【j】 表示   i經驗  j個怪的時候 所能用的最小忍耐度。


不過A了之後 去看別人寫的題解。  發現 用 d【i】【j】 表示 i 忍耐度 j個怪的時候 如果經驗 大於等於 n的時候 就是最優解。 這個好像更簡單 更好理解


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#include <fstream>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <vector>
#include <cmath>
#include <iomanip>
#include <cmath>
typedef long long LL;
typedef unsigned long long LLU;
const double PI=acos(-1.0);
using namespace std;
#define MAXN 100+21
#define INF 1 << 30
int d[MAXN][MAXN] = {0};
struct Game{
    int v;
    int de;
};
int main (){
    int n,m,k,s;
    while(scanf("%d%d%d%d",&n,&m,&k,&s) != EOF){
        for(int i = 0; i < MAXN; i++){
            for(int j = 0 ;j < MAXN; j++)
                d[i][j] = INF;
        }
        Game g[MAXN];
        for(int i = 1; i <= k; i++)
            scanf("%d%d",&g[i].v,&g[i].de);
        d[0][0] = 0;
        for(int i = 0; i <= n+20; i++){
            for(int j = 1; j <= s; j++){
                for(int z = 1; z <= k; z++){
                    if(i-g[z].v >= 0 && d[i-g[z].v][j-1]+g[z].de <= m && d[i-g[z].v][j-1] != INF)
                        d[i][j] = min(d[i][j],d[i-g[z].v][j-1]+g[z].de);
                }
            }
        }
        int M = INF;
        for(int j = n; j <= n+20; j++){
            for(int i = 0; i <= s; i++)
                M = min(M, d[j][i]);
        }
        if(M > m)
            printf("-1\n");
        else
            printf("%d\n",m-M);
    }
    return 0;
}


發佈了141 篇原創文章 · 獲贊 0 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章