HDU2159 FATE【二維費用揹包+完全揹包】
阿新 • • 發佈:2018-11-09
FATE
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 19336 Accepted Submission(s): 9093
Problem Description
最近xhd正在玩一款叫做FATE的遊戲,為了得到極品裝備,xhd在不停的殺怪做任務。久而久之xhd開始對殺怪產生的厭惡感,但又不得不通過殺怪來升完這最後一級。現在的問題是,xhd升掉最後一級還需n的經驗值,xhd還留有m的忍耐度,每殺一個怪xhd會得到相應的經驗,並減掉相應的忍耐度。當忍耐度降到0或者0以下時,xhd就不會玩這遊戲。xhd還說了他最多隻殺s只怪。請問他能升掉這最後一級嗎?
Input
輸入資料有多組,對於每組資料第一行輸入n,m,k,s(0 < n,m,k,s < 100)四個正整數。分別表示還需的經驗值,保留的忍耐度,怪的種數和最多的殺怪數。接下來輸入k行資料。每行資料輸入兩個正整數a,b(0 < a,b < 20);分別表示殺掉一隻這種怪xhd會得到的經驗值和會減掉的忍耐度。(每種怪都有無數個)
Output
輸出升完這級還能保留的最大忍耐度,如果無法升完這級輸出-1。
Sample Input
10 10 1 10
1 1
10 10 1 9
1 1
9 10 2 10
1 1
2 2
Sample Output
0 -1 1
Author
Xhd
Source
問題連結:HDU2159 FATE
解題思路:二維費用揹包+完全揹包。dp[i][j]表示忍耐度為i殺j只怪所能獲得的最大經驗值 。具體看程式
AC的C++程式碼:
#include<iostream> #include<algorithm> #include<cstring> using namespace std; const int N=105; const int INF=100000; int dp[N][N],a[N],b[N];//dp[i][j]表示忍耐度為i殺j只怪所能獲得的最大經驗值 int main() { int n,m,k,s; while(~scanf("%d%d%d%d",&n,&m,&k,&s)){ for(int i=0;i<k;i++) scanf("%d%d",&a[i],&b[i]);//得到的經驗值和會減掉的忍耐度 int res=INF; memset(dp,0,sizeof(dp)); for(int i=0;i<k;i++)//遍歷k只怪物 for(int j=b[i];j<=m;j++)//忍耐度為j for(int t=1;t<=s;t++){//殺t只怪 dp[j][t]=max(dp[j][t],dp[j-b[i]][t-1]+a[i]); if(dp[j][t]>=n) res=min(res,j); } if(res>m) printf("-1\n"); else printf("%d\n",m-res); } return 0; }
換一種思路,但是發現提交後WA
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=105;
const int INF=10000;
int dp[N][N],a[N],b[N];//dp[i][j]表示殺i只怪,獲得j經驗值需要消耗的最少忍耐度
int main()
{
int n,m,k,s;
while(~scanf("%d%d%d%d",&n,&m,&k,&s)){
for(int i=0;i<k;i++)
scanf("%d%d",&a[i],&b[i]);//得到的經驗值和會減掉的忍耐度
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
dp[i][j]=INF;
dp[0][0]=0;//殺0只怪只能獲得0經驗值,所需的最少忍耐度也為0
for(int i=0;i<k;i++)//遍歷k只怪物
for(int j=1;j<=s;j++)//殺j只怪物
for(int t=a[i];t<=n;t++)//獲得t經驗值
dp[j][t]=min(dp[j][t],dp[j-1][t-a[i]]+b[i]);
int res=INF;
for(int i=0;i<=s;i++)//尋找獲得經驗值n,殺小於等於s只怪所需的最少忍耐度
res=min(dp[i][n],res);
m-=res;
if(m<0) m=-1;
printf("%d\n",m);
}
return 0;
}