背包问题 2017-7-24
Posted Draymonder
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了背包问题 2017-7-24相关的知识,希望对你有一定的参考价值。
在N件物品取出若干件放在容量为W的背包里,每件物品的体积为W1,W2……Wn(Wi为整数),与之相对应的价值为P1,P2……Pn(Pi为整数)。求背包能够容纳的最大价值。
#include <iostream> #include <cstdio> #include <cmath> using namespace std; const int maxn = 100 + 5; int n ,w; int v[maxn],s[maxn]; int dp[2][10010]; int main() { cin>> n >> w; for(int i=1;i <= n;i++){ cin >> v[i] >> s[i]; } int now = 1,pre = 0; for(int i=1;i <= n;i++) { for(int j=0;j<=w;j++) { if(j < v[i]) dp[now][j] = dp[pre][j]; else dp[now][j] = max(dp[pre][j] , dp[pre][j-v[i]]+s[i]); // 不选 就是dp[i-1][j] //选就是dp[i-1][j-v[i]]+s[i] } swap (now,pre); } cout<< dp[pre][w]<<endl; return 0; }
下面是优化过内存的
#include <iostream> #include <cstdio> #include <cmath> #include <string.h> using namespace std; const int maxn = 100 + 5; int n ,w; int v[maxn],s[maxn]; int dp[10010]; int main() { cin>> n >> w; for(int i=1;i <= n;i++){ cin >> v[i] >> s[i]; } memset(dp,0,sizeof(dp)); for(int i=1;i <= n;i++) { for(int j=w;j >= v[i];j--)//从上面一个状态转移 但是倒着写 上面一个状态就不会转移了 dp[j] = max(dp[j] , dp[j-v[i]]+s[i]); } cout<< dp[w]<<endl; return 0; }
完全背包
在N种 物品取出若干件放在容量为W的背包里,每件物品的体积为W1,W2……Wn(Wi为整数),与之相对应的价值为P1,P2……Pn(Pi为整数)。求背包能够容纳的最大价值。
完全背包和01 背包的区别就是 能够存储的物品可以挑选多次
所以 转移方程也就变成了 dp[i][j] = max(dp[i-1][j] , dp[i][j-v[i]]+s[i]); // 不选 就是dp[i-1][j] 选就用dp[i][j-v[i]]+s[i]
//而01背包 就是dp[i][j] = max(dp[i-1][j] , dp[i-1][j-v[i]]+s[i])
#include <iostream> #include <cstdio> #include <cmath> using namespace std; const int maxn = 100 + 5; int n ,w; int v[maxn],s[maxn]; int dp[2][10010]; int main() { cin>> n >> w; for(int i=1;i <= n;i++){ cin >> v[i] >> s[i]; } int now = 1,pre = 0; for(int i=1;i <= n;i++) { for(int j=0;j<=w;j++) { if(j < v[i]) dp[now][j] = dp[pre][j]; else dp[now][j] = max(dp[pre][j] , dp[now][j-v[i]]+s[i]); // 不选 就是dp[i-1][j] //选就是dp[i][j-v[i]]+s[i] } swap (now,pre); } cout<< dp[pre][w]<<endl; return 0; }
下面也是优化过的
#include <iostream> #include <cstdio> #include <cmath> #include <string.h> using namespace std; const int maxn = 100 + 5; int n ,w; int v[maxn],s[maxn]; int dp[10010]; int main() { cin>> n >> w; for(int i=1;i <= n;i++){ cin >> v[i] >> s[i]; } memset(dp,0,sizeof(dp)); for(int i=1;i <= n;i++) { for(int j=v[i];j <= w;j++)//可以从上面一个状态转移 正着写 就能覆盖上次的计算了 dp[j] = max(dp[j] , dp[j-v[i]]+s[i]); } cout<< dp[w]<<endl; return 0; }
以上是关于背包问题 2017-7-24的主要内容,如果未能解决你的问题,请参考以下文章