hdu 2159 FATE(二維揹包+完全揹包)

天天一道dp~這道dp依舊是昨天的問題,看問題思考了很長時間,中間實驗室根本安靜不下來,帶上耳機也無法認真的思考,可能還是老衲定力不足吧,聽押尾光太郎的指彈確實是無法全心取思考問題啊~(差點忘記這是題解了,汗
題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=2159
題意:中文的,中國大學生應該都能看懂吧~
思路:這題我思考了很久,可能是我比較笨也比較懶吧(寧可自己寫題解也不願去在網上找題解。
這題和普通揹包比多了一個限制,這題的限制有:經驗要達到要求,疲勞值不能超過極限
怪可以殺無限次,完全揹包。如果不知道爲什麼選完全揹包,推薦看揹包九講。
揹包九講:http://love-oriented.com/pack/
所以可以先找到這題的最大經驗,判斷這個經驗有沒有達到要求的經驗,如果達到了就ok,再找到達到經驗值消耗最小疲勞值就好了。
代碼:

#include<cstdio>
#include<cstring>
#include<iostream>
const int maxn = 10010;
using namespace std;

struct Xhd{
    int j;
    int p;
}xhd[200];

int main(){
    int n , m , k , s , jy[200] , pl[maxn];
    while(~scanf("%d%d%d%d",&n,&m,&k,&s)){
        memset(jy,0,sizeof(jy));
        memset(pl,maxn,sizeof(pl));
        pl[0] = 0;
        for(int i = 1;i <= k; i++)
          scanf("%d%d",&xhd[i].j,&xhd[i].p);
        for(int i = 1;i <= k; i++) //先用完全揹包找到最大的經驗值
          for(int j = 1;j <=s ; j++)
           jy[j] = max(jy[j] , jy[j-1]+xhd[i].j);
        if(jy[s]<n){
            printf("-1\n");
            continue;
        }
        for(int i = 1; i <= k; i++) //再用完全揹包找到達到經驗的最小疲勞值
          for(int j = xhd[i].j; j <= jy[s]; j++)
            pl[j] = min(pl[j],pl[j-xhd[i].j]+xhd[i].p);
        int min;
        for(int j = n;j <= jy[s]; j++){
            if(j == n) min = pl[j];
            else if(pl[j] < min) min = pl[j];
        }
        if(min == maxn||min > m) printf("-1\n");
        else printf("%d\n",m-min);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章