P1776 宝物筛选

和这道题几乎一模一样:https://www.cnblogs.com/zxr000/p/16999729.html
实现:

#include <bits/stdc++.h>
using namespace std;
const int N = 4e4 + 5;
int f[N], n, m;
struct Good
{
    int w, v;
} good[N];
int main()
{
    scanf("%d%d", &n, &m);
    // 遍历物品
    while (n--)
    {
        int v, w, s;
        scanf("%d%d%d", &w, &v, &s);
        // 记录分成多少块
        int cnt = 1;
        for (int i = 1; i <= s; i *= 2)
        {
            // 分成2^k次方的时候
            // 新物品的体积和价值 = 选的个数 *单个的体积和价格
            good[cnt].v = i * v;
            good[cnt++].w = i * w;
            s -= i;
        }

        // 最后一个物品
        if (s > 0)
        {
            good[cnt].v = s * v;
            good[cnt++].w = s * w;
        }

        // 现在相当于变成了01背包
        // 遍历物品
        for (int i = 1; i < cnt; i++)
            // 遍历体积,由于滚动了一维,所以一定要逆序遍历
            for (int j = m; j >= good[i].v; j--)
                f[j] = max(f[j], f[j - good[i].v] + good[i].w);
    }
    printf("%d\n", f[m]);
    return 0;
}
posted @ 2022-12-23 00:17  zxr000  阅读(20)  评论(0编辑  收藏  举报