背包问题

// bag_pro.cpp : 定义控制台应用程序的入口点。
//


// stdafx.cpp : 只包括标准包含文件的源文件
// bag.pch 将作为预编译头
// stdafx.obj 将包含预编译类型信息


// TODO: 在 STDAFX.H 中引用任何所需的附加头文件,
//而不是在此文件中引用
// bag.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"


#include<iostream>
#include<algorithm>
#define maxsize 200

using namespace std;

/*
有一个容量为V的背包,和一些物品。这些物品分别有两个属性,体积w和价值v,
每种物品只有一个。要求用这个背包装下价值尽可能多的物品,求该最大价值,
背包可以不被装满。因为最优解中,每个物品都有两种可能的情况,即在背包中
或者不存在(背 包中有0个该物品或者 1个),所以我们把这个问题称为0-1背
包问题。
n个物品;m代表背包容量;w代表每个物体的体积;v代表每个物体的价值
dp[i][j] = max{dp[i-1][j-v[i]] + w[i],dp[i-1][j]};


改进:
dp[i-1][j]}的特点,当前状态仅依赖前一状态的剩余体积与当前物品体积v[i]
的关系。根据这个特点,我们可以将dp降到一维
即dp[j] = max{dp[j],dp[j-w[i]]+v[i]}。从这个方程中我们可以发现,
有两个dp[j],但是要区分开。等号左边的dp[j]是当前i的状态,右边中括号内
的dp[j]是第i-1状态下的值。
测试数据
//in.txt:
5 100
77 92
22 22
29 87
50 46
99 90
//out.txt
133
//in.txt:
8 200
79 83
58 14
86 54
11 79
28 72
62 52
15 48
68 62
//out.txt
334
复杂度:o(n*m)
*/
int w[maxsize], v[maxsize], dp[maxsize];
int main()
{
    int n, m;        //n代表物品的个数,m代表背包总容量

    cin >> n >> m;
    for (int i = 1; i <= n; i++)
    {
        cin >> w[i] >> v[i];
    }
//初始化
    for (int i = 1; i <= m; i++)
    {
        dp[i] = 0;
    }
// 找最优解
    for (int i = 1; i <= n; i++)    //i从1开始
    {
//只有 j > w[i] , dp[i][j] 才能取最大值,否则dp[j]将不作更新,等于dp[i-1][j]
        for (int j =m; j > w[i]; j--)
        {
            dp[j] = max(dp[j], dp[j - w[i]] + v[i]);
        }
    }
    cout << dp[m] << endl;

    system("pause");
    return 0;

}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值