蕾凹娜的哀伤「掘金日新计划 · 12 月更文挑战」

53 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第11天,点击查看活动详情

蕾凹娜的哀伤

链接:ac.nowcoder.com/acm/contest…
来源:牛客网

题目描述

这一天光年神话要进行团建采购,爱要面子的钢板狮子对着der说,你带着这个购物车去超市随便买能装下就行。
这个购物车很神奇,装东西只需要考虑体积而不用考虑形状。
这个购物车的容积为V。
超市有N种商品,每种的体积为ti​ ,价钱为wi​ ,数量为si​

der是不会给钢板狮子省钱的

der想知道在购物车容积内,她最多能花掉多少钱 。

输入描述:

第一行一个整数N
0<N≤3000
第二行一个整数V
0<V≤20000
以下N行每行三个整数ti​,wi​,si​
0<ti​,wi​,si​≤20000

输出描述:

输出一个整数

示例1

输入

20
200
80 38 8
71 92 2
69 30 9
45 33 1
78 30 8
4 51 8
4 94 9
1 93 2
48 31 9
41 29 7
93 56 4
95 6 4
35 23 8
100 42 1
9 87 9
60 10 9
74 16 10
77 50 2
73 87 9
71 12 10

输出

2256

思路

看题之后就会发现,他要求装东西需要考虑体积不考虑形状。只要想办法将装入的东西的体积控制在尽可能离V最近的体积。所以就会想到完全背包的问题,结合完全背包的板子,会发现是恰好满足的,而且没有其他的附加条件,所以说就直接生搬硬套板子就好啦。(qwq,同样如果没有板子的话建议准备一个)这个题是最直接的完全背包问题。

代码

#include<bits/stdc++.h>
using namespace std;
#define int long long
struct node{
    int w;
    int v;
};
struct node gouwu[20000010];
signed main(){
    int n,V;
    int f[2000010];
    int k,t,count,w,v,m;
    count=0;
    memset(f,0,sizeof(f));
    cin>>n>>V;
    for(int i=1;i<=n;i++){
        cin>>w>>v>>m;
        k=1;
        while(m-k>0){
            m-=k; 
            gouwu[++count].w=k*w;
            gouwu[count].v=k*v; 
            k*=2; 
        }
        gouwu[++count].w=m*w;
        gouwu[count].v=m*v;
    }
    for(int i=1;i<=count;i++)
        for(int j=V;j>=gouwu[i].w ;j--)
            f[j]=max( f[j],f[j-gouwu[i].w]+gouwu[i].v); 
    cout<<f[V]<<endl;
    return 0;
}