码迷,mamicode.com
首页 > 其他好文 > 详细

背包问题 2017-7-24

时间:2017-07-24 11:26:58      阅读:163      评论:0      收藏:0      [点我收藏+]

标签:tps   class   event   iostream   name   https   close   div   include   

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

标签:tps   class   event   iostream   name   https   close   div   include   

原文地址:http://www.cnblogs.com/Draymonder/p/7227276.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!