01背包问题,dp和贪心解法(c++11)

dp解法:

令dp[i]表示容量为i的背包所能得到的最大价值,考虑在当前物品集合中加入1个新考虑的物品i,则有如下状态转移方程:dp[j] = max(dp[j], dp[j - weight[i]] + value[i])

#include <bits/stdc++.h>
using namespace std;

const int M = 1e4;
typedef pair<int, vector<int> > piv;

struct Node {
    int weight, value;
    int id;
    void read() {
        cin >> weight >> value;
    }
    void solve(piv dp[], int M) {
        for (int i = M; i >= weight; i --) {
            if (dp[i - weight].first + value > dp[i].first) {
                dp[i].first = dp[i - weight].first + value;
                dp[i].second = dp[i - weight].second;
                dp[i].second.push_back(id);
            }
        }
    }
};

int n, m;
piv dp[M];

int main() {
    puts("请输入背包容量和物品个数:");
    cin >> m >> n;
    puts("请输入每个背包的重量(体积)和价值");
    Node things;
    for (int i = 0; i < n; i ++) {
        things.read();
        things.id = i + 1;
        things.solve(dp, m);
    }
    cout << "最大价值为:" << dp[m].first << endl;
    puts("选择的物品编号:");
    for (int i = 0; i < dp[m].second.size(); i ++) {
        cout << dp[m].second[i] << " ";
    }
    cout << endl;
    return 0;
}

贪心解法:

按部分背包的贪心策略,优先考虑单位价值高的物品,于是只需要按单位价值从高到低排序,然后依次考虑,能放则放即可。

#include <bits/stdc++.h>
using namespace std;

const int N = 1e2;

struct Node {
    int weight, value;
    int id;
    void read() {
        cin >> weight >> value;
    }
    // 单位价值高的放前面
    bool operator< (const Node &that) const {
        return value * that.weight > that.value * weight;
    }
};
Node things[N];
int n, m;

int main() {
    puts("请输入背包容量和物品个数:");
    cin >> m >> n;
    puts("请输入每个背包的重量(体积)和价值");
    for (int i = 0; i < n; i ++) {
        things[i].read();
        things[i].id = i + 1;
    }
    sort(things, things + n);
    int ans = 0;
    vector<int> V;
    for (int i = 0; i < n; i ++) {
        if (m >= things[i].weight) {
            ans += things[i].value;
            m -= things[i].weight;
            V.push_back(things[i].id);
        }
    }
    cout << "最大价值为:" << ans << endl;
    puts("选择的物品编号为:");
    for (int i = 0; i < V.size(); i ++) {
        cout << V[i] << " ";
    }
    cout << endl;
    return 0;
}

  

时间: 2024-11-05 14:41:53

01背包问题,dp和贪心解法(c++11)的相关文章

【动态规划】01背包问题_两种解法

问题描述 0-1背包问题:给定\(n\)种物品和一背包.物品i的重量是\(w_i\),其价值为\(v_i\),背包的容量为\(C\).问:应该如何选择装入背包的物品,使得装人背包中物品的总价值最大? 在选择装人背包的物品时,对每种物品\(i\)只有两种选择,即装人背包或不装入背包.不能将物品\(i\)装入背包多次,也不能只装入部分的物品\(i\).因此,该问题称为0-1背包问题. 此问题的形式化描述是,给定\(C>0\),\(w_i>0\),\(v_i>0\),\(1≤i≤n\),要求找

01背包问题--动态规划解法

从01背包问题理解动态规划 01背包问题具体例子:假设现有容量10kg的背包,另外有3个物品,分别为a1,a2,a3.物品a1重量为3kg,价值为4:物品a2重量为4kg,价值为5:物品a3重量为5kg,价值为6.将哪些物品放入背包可使得背包中的总价值最大? 这个问题有两种解法,动态规划和贪婪算法.本文仅涉及动态规划. 先不套用动态规划的具体定义,试着想,碰见这种题目,怎么解决? 首先想到的,一般是穷举法,一个一个地试,对于数目小的例子适用,如果容量增大,物品增多,这种方法就无用武之地了. 其次

PAT 甲级 1068 Find More Coins (30 分) (dp,01背包问题记录最佳选择方案)***

1068 Find More Coins (30 分)   Eva loves to collect coins from all over the universe, including some other planets like Mars. One day she visited a universal shopping mall which could accept all kinds of coins as payments. However, there was a special

0-1背包问题的动态规划实现

一,问题描述 给定一个背包,已知背包的最大承重为packageWeight,再给出若干件(numbers件)物品,已经每件物品的重量和对应的价值. 物品的重量存储在weight[]数组中,物品的价值存储在value[]数组中. 现在要求:应该挑选哪几件物品,使得背包装下最大的价值(注意:装的物品的重量不能超过背包的承重) (本文在最后打印出了装入了哪几件物品) 二,问题分析 这是一个典型的动态规划求解.对于每件物品而言,只有两种选择,要么选中它装入背包:要么不选它.因此,这是一个0-1背包问题,

0-1背包问题,附上例题(POJ - 3624 Charm Bracelet)

0-1背包问题的题目样式 有 N 件物品和一个容量为 M 的背包.放入第 i 件物品耗费的费用是 Wi,得到的价值是 Vi.求解将哪些物品装入背包可使价值总和最大. 0-1背包问题关键在于该物品放或不放,即在当前容量为M的的情况下,选择不选择该物品,那么就有一个转移方程 for(i=0  -  N) for(j=0  -  M) dp[i][j] = max(dp[i-1][j],dp[i-1][j+w[i]]+v[i]); 当前物品为i,当前的背包容量为j,如果不选当前该物品,则选取dp[i-

01背包问题(空间优化)经典代码

题目 有N件物品和一个容量为V的背包.第i件物品的费用是c[i],价值是w[i].求解将哪些物品装入背包可使价值总和最大. 基本思路 这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放. 用子问题定义状态:即f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值.则其状态转移方程便是: f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]} 这个方程非常重要,基本上所有跟背包相关的问题的方程都是由它衍生出来的.所以有必要将它详细解释一下

01背包问题的动态规划算法

01背包问题我最初学会的解法是回溯法,第一反应并不是用动态规划算法去解答.原因是学习动态规划算法的时候,矩阵连乘.最长公共子串等问题很容易将问题离散化成规模不同的子问题,比较好理解,而对于01背包问题则不容易想到将背包容量离散化抽象出子问题,从情感上先入为主也误以为动态规划算法不是解决01背包问题的好方法,实际上并不是这样的.另外,动态规划算法不对子问题进行重复计算,但是要自底向上将所有子问题都计算一遍,直到计算出最终问题的结果也就是我们要的答案,有点像爬山的感觉. 问题描述:给定n种物品和一背

算法学习 - 01背包问题(动态规划C++)

动态规划 01背包 问题描述 求解思路 代码实现 放入哪些物品 代码 动态规划 我在上一篇博客里已经讲了一点动态规划了,传送门:算法学习 - 动态规划(DP问题)(C++) 这里说一下,遇到动态规划应该如何去想,才能找到解决办法. 最主要的其实是要找状态转移的方程,例如上一篇博客里面,找的就是当前两条生产线的第i个station的最短时间和上一时刻的时间关系. minTime(station[1][i]) = minTime(station[1][i-1] + time[i], station[

《算法导论》读书笔记之第16章 0-1背包问题—动态规划求解

原文:http://www.cnblogs.com/Anker/archive/2013/05/04/3059070.html 1.前言 前段时间忙着搞毕业论文,看书效率不高,导致博客一个多月没有更新了.前段时间真是有些堕落啊,混日子的感觉,很少不爽.今天开始继续看算法导论.今天继续学习动态规划和贪心算法.首先简单的介绍一下动态规划与贪心算法的各自特点及其区别.然后针对0-1背包问题进行讨论.最后给出一个简单的测试例子,联系动态规划实现0-1背包问题. 2.动态规划与贪心算法 关于动态规划的总结