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

背包DP

时间:2020-01-28 00:01:14      阅读:86      评论:0      收藏:0      [点我收藏+]

标签:超过   include   复杂   out   i++   clu   复杂度   优化   problem   

0-1背包

有n种物品,每种只有一个。第i种物品的体积为Vi,重量为Wi。选一些 物品装到一个容量为C的背包,使得背包内物品在总体积不超过C的前提下重量尽量大。
$f[i][j]=max(f[i-1][j],f[i-1][j-v[i]]+w[i])$

for(int i = 1; i <= n; i++) {
    for(int j = 0; j <= c; j++) {
        f[i][j] = f[i - 1][j];
        if(j >= v[i]) f[i][j] = max(f[i][j], f[i - 1][j - v[i]] + w[i]);
    }
}

可以用滚动数组进行优化。

for(int i = 1; i <= n; i++)
    for(int j = c; j >= v[i]; j--)
        f[j] = max(f[j], f[j - v[i]] + w[i]);

例题:洛谷P1060

https://www.luogu.com.cn/problem/P1060

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

int n, c, v, p, f[30010];

int main() {
    cin >> n >> c;
    for(int i = 0; i < n; i++) {
        cin >> v >> p;
        for(int j = c; j >= v; j--)
            f[j] = max(f[j], f[j - v] + v * p);
    }
    cout << f[c];
}

 

完全背包

有n种物品,每种均有无穷多个。第i种物品的体积为Vi,重量 为Wi。选一些物品装到一个容量为C的背包中,使得背包内物品在总体积不超过C的前提下重量尽量大。

$f[i]=max(f[i-v[j]]+w[j])$

for(int i = 1; i <= n; i++)
    for(int j = v[i]; j <= c; j++)
        f[j] = max(f[j], f[j - v[i]] + w[i]);

例题:洛谷P1616
https://www.luogu.com.cn/problem/P1616

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

int n, c, v, w, f[100010];

int main() {
    cin >> c >> n;
    for(int i = 0; i < n; i++) {
        cin >> v >> w;
        for(int j = v; j <= c; j++)
            f[j] = max(f[j], f[j - v] + w);
    }
    cout << f[c];
}

 

多重背包

有n种物品,每种均有无穷多个。第i种物品的体积为Si,重量 为Wi。选一些物品装到一个容量为C的背包中,使得背包内物品在总体积不超过C的前提下重量尽量大。
直接摊平就转化为0-1背包,但时间复杂度会很差。可以使用二分法优化。

例题:洛谷P1776
https://www.luogu.com.cn/problem/P1776

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

long long n, c, v[100010], w[100010], f[100010], x, y, z, p = 0;

int main() {
    cin >> n >> c;
    for(int i = 0; i < n; i++) {
        cin >> x >> y >> z;
        for(int j = 1; j <= z; j <<= 1) {
            v[++p] = y * j;
            w[p] = x * j;
            z -= j;
        }
        if(z) v[++p] = y * z, w[p] = x * z;
    }
    for(int i = 1; i <= p; i++)
        for(int j = c; j >= v[i]; j--)
            f[j] = max(f[j], f[j - v[i]] + w[i]);
    cout << f[c];
}

背包DP

标签:超过   include   复杂   out   i++   clu   复杂度   优化   problem   

原文地址:https://www.cnblogs.com/nioh/p/12237080.html

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