动态规划☞背包问题(⊙o⊙)…

来源:互联网 发布:如何设置淘宝客推广 编辑:程序博客网 时间:2024/06/11 13:31

啦啦啦啦啦啦~(≧▽≦)/~

因为看这个的时候在听好妹妹的冬。
所以。。。嗯就这样开头咯。

背包问题的第一个小问题,01背包问题,action:

杭电2602例题 Bone Collector

首先要知道背包问题的基本构成嘛
有几个东西,背包可以装多少东西即体积,
然后几个东西分别的体积与价值,最后希望可以装下价值最大的东西。

问题可以转化为:每种物品仅一件,放入背包吗。
即:为了使背包的价值最大化,第i件物品放还是不放。
所以我们用了两个循环来模拟所有情况:

#include"iostream"#include"algorithm"#include"string.h"using namespace std;int main(){    int T;    cin >> T;    while (T--)    {        int N, V;        cin >> N >> V;        int value[1010];        int weight[1010];        int f[1010][1010];        memset(value, 0, sizeof(value));        memset(weight, 0, sizeof(weight));        memset(f, 0, sizeof(f));        for (int i = 1; i <= N; i++)            cin >> value[i];        for (int i = 1; i <= N; i++)            cin >> weight[i];        for (int i = 1; i <= N; i++)            for (int j = 1; j <= V; j++)                if (weight[i] <= j)                    f[i][j]=max(f[i][j], f[i - 1][j - weight[i]] + value[i]);                else                    f[i][j] = f[i - 1][j];            cout << f[N][V] << endl;    }    return 0;}``

这里我们会发现空间复杂度能够降低
第二个循环可以逆序来跑,这样就不会重复去跑空间不够的东西了,而且可以把数组变成一维数组。
当他是二维数组的时候,f[i][j]的含义是指前i件物品放入容量为v的背包中的价值。
而成为一维数组的时候,f[i]的含义是当空间为i时,放入背包的最大价值。

所以优化后的程序为:

#include"iostream"#include"algorithm"#include"string.h"using namespace std;int main(){    int T;    cin >> T;    while (T--)    {        int N, V;        cin >> N >> V;        int value[1010];        int weight[1010];        int f[1010];        memset(value, 0, sizeof(value));        memset(weight, 0, sizeof(weight));        memset(f, 0, sizeof(f));        for (int i = 1; i <= N; i++)            cin >> value[i];        for (int i = 1; i <= N; i++)            cin >> weight[i];        for (int i = 1; i <= N; i++)            for (int j = V; j >= weight[i]; j--)                f[j] = max(f[j], f[j - weight[i]] + value[i]);        cout << f[V] << endl;    }    return 0;}

以上两个程序是杭电2602 Bone Collector的程序。
也是01背包的常见标程~

(⊙v⊙)嗯完全背包问题先不写啦