hdu2159 FATE 经典二维背包
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2159
思路:
定义ans存当前满足条件的消耗的最小的忍耐值(满足条件的忍耐值为在当前消耗的忍耐值的情况下,获得的经验值大于等于n)。
定义dp[i][j],表示杀i只怪,消耗j个忍耐值的获得 的最大的经验值,
那么状态转移方程很容易得出:dp[i][j]=max(dp[i][j],dp[i-1][j-c[i]]+v[i]);
代码如下:(如果看不懂,可以先看一下背包九讲)
1 #include<iostream>//经典二维完全背包模型 2 #include<cstdlib> 3 #include<cstdio> 4 #include<cstring> 5 using namespace std; 6 #define INF 1000000010 7 int dp[200][200];//dp[i][j] 8 int v[200],c[200]; 9 int main() 10 { 11 int n,m,k,s; 12 while(scanf("%d%d%d%d",&n,&m,&k,&s)!=EOF) 13 { 14 int ans=INF; 15 memset(dp,0,sizeof(dp)); 16 memset(v,0,sizeof(v)); 17 memset(c,0,sizeof(c)); 18 for(int i=1;i<=k;i++) 19 { 20 scanf("%d%d",&v[i],&c[i]); 21 } 22 23 for(int i=1;i<=k;i++) 24 for(int z=1;z<=s;z++) 25 for(int j=c[i];j<=m;j++) 26 { 27 dp[z][j]=max(dp[z][j],dp[z-1][j-c[i]]+v[i]); 28 if(dp[z][j]>=n){ 29 ans=min(j,ans); 30 } 31 } 32 if(ans==INF) cout<<"-1"<<endl; 33 else cout<<(m-ans)<<endl; 34 35 } 36 return 0; 37 }