题解:P11297 [NOISG2018 Prelim] Knapsack
题意简单,就是一个多重背包。
但是这题的数据范围实在是反常。
我们发现这题的容量出奇的小,可以接受
多重背包的标准复杂度最优是
首先看向这个
还没完,如果我们只看同种重量的物品,我们也只需要观察价值前
简单分析一下现在物品数量的上界,是
我们直接对这些剩下的物品做简单的
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+5;
const int SN=2005;
int n,S;
struct node{
int v,w,k;
bool operator<(node x){
return v<x.v;
}
}a[N];
struct nd{
int v,w;
}it[SN*30];
vector<node> item[SN];
int cnt;
int f[SN];
signed main(){
cin>>S>>n;
for(int i=1;i<=n;i++){
cin>>a[i].v>>a[i].w>>a[i].k;
item[a[i].w].push_back(a[i]);
}
for(int i=1;i<=S;i++) sort(item[i].begin(),item[i].end());
for(int i=1;i<=S;i++){
int j=0;
while(j<=S/i and !item[i].empty()){
it[++cnt]={item[i].back().v,item[i].back().w};
j++;
item[i].back().k--;
if(!item[i].back().k) item[i].pop_back();
}
}
for(int i=1;i<=cnt;i++){
for(int j=S;j>=it[i].w;j--){
f[j]=max(f[j],f[j-it[i].w]+it[i].v);
}
}
cout<<f[S];
}