NC16671 [NOIP2006]金明的预算方案

题目

  • 原题地址:[NOIP2006]金明的预算方案
  • 题目编号:NC16671
  • 题目类型:DP、分组背包
  • 时间限制:C/C++ 1秒,其他语言2秒
  • 空间限制:C/C++ 32768K,其他语言65536K

1.题目大意

  • 总钱数为n,有m个物品,每个物品有价格v,重要度p,从属关系q,求不超过总钱数,可以得到的重要度与价格乘积的最大值。

2.题目分析

  • v存价格,p存重要度与价格的乘积,q存从属关系,f[i]存使用钱数不超过i时的可获得的最大乘积值,g[i]存中间计算量
  • 每次选择主物品,初始化数组g,更新g为容量为k时不选择从物品和容量为k-v[j]时选择选择从物品的乘积最大值
  • 最后用g来更新f,取每个元素的较大者为新的f

3.题目代码

#include <bits/stdc++.h>

using namespace std;

int n, m, v[66], p[66], q[66], g[32003], f[32003];

int main() {
    cin >> n >> m;
    for(int i=1;i<=m;i++) cin >> v[i] >> p[i] >> q[i], p[i] *= v[i];
    for(int i=1;i<=m;i++) {if(!q[i]) {
        for(int j=v[i];j<=n;j++) g[j] = f[j-v[i]] + p[i];
        for(int j=1;j<=m;j++) if(q[j]==i)
            for(int k=n;k>=v[i]+v[j];k--)
                g[k] = max(g[k], g[k-v[j]]+p[j]);
        } for(int j=1;j<=n;j++) f[j] = max(f[j], g[j]);
    } cout << f[n] << endl;
}
posted @ 2022-09-13 13:49  仪战群儒  阅读(52)  评论(0)    收藏  举报