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;
}

  

posted @ 2015-10-29 18:34  jklongint  阅读(927)  评论(0编辑  收藏  举报