一种好像不需要考虑附件多少的做法

P1064 [NOIP2006 提高组] 金明的预算方案

z_y_x_ @ 2022-10-04 13:20:36

题目已经明确说明最多两个附件,很多题解都是分五种决策

然而我的做法是把每一组都开一个vector,每当一组新加一个物品时就增加几种决策(打包每一种决策的体积与总价值)

这样是不需要考虑附件有多少个的。已经过了,如果有问题的话各位dalao尽管指出~

#include <iostream>
#include <algorithm>
#include <vector>

#define v first
#define w second

using namespace std;

typedef pair<int, int> PII;

const int N = 70, M = 32010;

vector<PII> goods[N];
int f[N][M]; //第一维好像优化不了,因为不考虑每一组物品多少,每一组物品的所有方案都打包,dp过程中可能会一组"重复买" 
int n, m;

int main()
{
    scanf("%d%d", &m, &n);

    int a, b, c;
    for (int i = 1; i <= n; i ++ ){
        scanf("%d%d%d", &a, &b, &c);

        if (!c) goods[i].push_back({a, a * b});
        else{
            for (int j = goods[c].size() - 1; j >= 0; j -- ){
                PII t = goods[c][j]; //t可能是c组种的多个物品打包的结果 
                goods[c].push_back({t.v + a, t.w + a * b}); 
            }
        }
    }

    for (int i = 1; i <= n; i ++ ){
        for (int j = 0; j <= m; j ++ )
            f[i][j] = f[i - 1][j]; //由于有两维,所以要更新为上一组的情况 

        for (int j = goods[i].size() - 1; j >= 0; j -- ){
            PII t = goods[i][j];
            for (int k = m; k >= t.v; k -- )
                f[i][k] = max(f[i][k], f[i - 1][k - t.v] + t.w);
        }
    }

    printf("%d\n", f[n][m]);

    return 0;
}

by Judgelight @ 2022-10-05 08:55:44

@z_yx

orz


by z_y_x_ @ 2022-10-05 08:58:51

@L_B_L sto


|