天天一道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;
}