背包问题 2017-7-24

Posted Draymonder

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了背包问题 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的主要内容,如果未能解决你的问题,请参考以下文章

防止导航到同一个片段

2017.7.24-2017.7.30

使用喷气背包导航将自定义过渡动画添加到底部导航设置

2017.7.24

python日记----2017.7.24

第二组项目冲刺(Beta版本)第六次每日例会 2017/7/24