• acwing3. 完全背包问题


    有 N 种物品和一个容量是 V 的背包,每种物品都有无限件可用。

    第 i 种物品的体积是 vi,价值是 wi。

    求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。
    输出最大价值。

    输入格式

    第一行两个整数 N,V,用空格隔开,分别表示物品种数和背包容积。

    接下来有 N 行,每行两个整数 vi,wi,用空格隔开,分别表示第 i 种物品的体积和价值。

    输出格式

    输出一个整数,表示最大价值。

    数据范围

    0<N,V≤1000
    0<vi,wi≤1000

    输入样例

    4 5
    1 2
    2 4
    3 4
    4 5
    

    输出样例:

    10
    

    方法一:

    f(i, j)表示背包容量 j 选前 i 种物品得到的最大价值,于是有

    一式:f(i, j) = max(f(i-1, j), f(i-1, j-v)+w, f(i-1, j-2v)+w...., f(i-1, j-kv)+kw),其中 kv <= j

    化简用到的trick: 利用错位相减,令j = j-v,有

    二式:f(i, j-v) = max(f(i-1, j-v), f(i-1, j-2v)+w, f(i-1, j-3v)+w....)

    结合两式,一式简化成

    f(i, j) = max(f(i-1, j), f(i, j-v)+w)

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int N = 1010;
    int n, v, a[N], b[N], f[N];
    
    // f(i, j)   = max(f(i-1, j), f(i-1, j-v)+w, f(i-1, j-2v)+2w)...
    // f(i, j-1) = max(f(i-1, j-v), f(i-1, j-2v)+w, f(i-1, j-3v)+2w)...
    
    // 错位相减得
    // f(i, j) = max(f(i-1, j), f(i, j-v) + w)
    
    int main() {
        scanf("%d%d", &n, &v);
        for (int i = 1; i <= n; ++i)
            scanf("%d%d", &a[i], &b[i]);
    
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= v; ++j) {
                if (j >= a[i])
                    f[j] = max(f[j], f[j-a[i]]+b[i]);
            }
        }
        printf("%d", f[v]);
    }
    
  • 相关阅读:
    vi 整行 多行 复制与粘贴
    FPGA设计—UVM验证篇 Hello world
    武汉市最大的二手车市场
    vim 使用技巧
    CentOS 7下的软件安装方法及策略
    搜索插件:ack.vim
    Vim插件管理
    【一】 sched.h
    Android USB驱动源码分析(-)
    在Python中反向遍历序列(列表、字符串、元组等)的五种方式
  • 原文地址:https://www.cnblogs.com/nosae/p/16001253.html
Copyright © 2020-2023  润新知