多重背包的单调队列优化
https://blog.csdn.net/flyinghearts/article/details/5898183
完美的讲解
POJ2392
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#include<iostream>
using namespace std;
#define endl "\n"
#define inf 0x3f3f3f3f
#define me(a,b) memset(a,b,sizeof(a))
const int maxn=1005;
const int MAX_V = 400004;
pair<int,int> q[MAX_V];
inline void pack(int f[], int V, int v, int n, int w) {
if (n == 0 || v == 0)
return;
if (n == 1) { //01背包
for (int i = V; i >= v; --i)
if (f[i] < f[i - v] + w)
f[i] = f[i - v] + w;
return;
}
if (n * v >= V - v + 1) {
for (int i = v; i <= V; ++i)
if (f[i] < f[i - v] + w)
f[i] = f[i - v] + w;
return;
}
for(int j=0;j<v;j++){
int head=1,rear=1;
for(int k=j,i=0;k<=V;k+=v,i++){
int tt=f[k]-i*w;
while(rear!=head&&q[rear].first<tt) --rear;
q[++rear]=make_pair(tt,i);
if(head!=rear&&(i-q[head+1].second)>n) ++head;
f[k]=q[head+1].first+i*w;
}
}
}
int f[40000+5];
int n;
int h[maxn],a[maxn],c[maxn];
int p[maxn];
bool cmp(int x,int y) {
return a[x]<a[y];
}
int main() {
cin>>n;
for(int i=1; i<=n; i++)
scanf("%d%d%d",&h[i],&a[i],&c[i]),p[i]=i;
sort(p+1,p+n+1,cmp);
for(int i=1; i<=n; i++) {
int t=p[i];
pack(f,a[t],h[t],c[t],h[t]);
}
printf("%d",*max_element(f,f+a[p[n]]+1));
}
浙公网安备 33010602011771号