仅做为能让自己理解的笔记(这两天连题解都看不懂实在痛苦QAQ)
#include<iostream>
#include<cstring>
using namespace std;
const int N = 20002;
int pre[N],now[N],q[N];
//附加价值:剔除所有自身价值的剩余价值
int main(){
int n,m;//总个数,总体积
cin>>n>>m;
int v,w,s;//体积,价值,个数
for(int i = 0;i<n;i++){
cin>>v>>w>>s;
for(int k = 0;k<v;k++){
//将相同的体积的余数放入队列打包
int h = 0,t = -1;
//单调队列头,尾指针
for(int j = k;j<=m;j+=v){
pre[j] = now[j];//状态转移
if(h<=t&&j-q[h]>s*v){
//4.队列中排队的个数大于个数(s)时
//(虽然凭我贫瘠的想象力想不出价值负增长的情况是怎么样的。。。)
h++;
//丢掉头指针
}
if(h<=t){
now[j] = max(pre[q[h]]+(j-q[h])/v*w,now[j]);
//2.将当前个数的附加价值与队列首指针指向的比较
}
if(h<=t&&pre[q[t]]-(q[t]-k)/v*w<=pre[j]-(j-k)/v*w){
//(这里按道理是要用while的,毕竟要全对比一遍,但也不知道为什么用if也能通过???)
//3.当前个数的附加价值对比先前个数的(尾指针指向的)较大或相等时
t--;
//队列 抛弃尾指针指向的附加价值
}
q[++t] = j;
//1.输入尾指针
}
}
}
cout<<now[m];
return 0;
}
希望以后别忘了(立了个flag?)
这次忘的有点彻底。。。
果然又忘了。。。