首页 > 代码库 > 背包问题 2017-7-24

背包问题 2017-7-24

01 背包

在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;}
01 背包

 下面是优化过内存的

技术分享
#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;}
01 背包优化

 

完全背包

在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