https://www.luogu.org/problemnew/show/P1776

 单调队列+多重背包的讲解https://www.cnblogs.com/JoeFan/p/4165956.html         https://blog.csdn.net/flyinghearts/article/details/5898183

 

#include<iostream>
#include<algorithm>
#include<deque>
using namespace std;
int n,V;
int ans=0,dp[40010];
deque<int> q2,q;
int main(){
    cin>>n>>V;
    for(int o=0;o<n;o++){
        int w,v,c;
        cin>>w>>v>>c;
        if(v==0){
            ans+=w*c;
            continue;
        }
        int k=V/v;
        c=min(c,k);
        for(int d=0;d<v;d++){
            q.clear();
            q2.clear();
            k=(V-d)/v;
            for(int j=0;j<=k;j++){
                while(!q.empty()&&dp[j*v+d]-j*w>=q2.back()){
                    q2.pop_back();    
                    q.pop_back();                
                }
                q.push_back(j);
                q2.push_back(dp[j*v+d]-j*w);
                while(!q.empty()&&q.front()+c<j){
                    q.pop_front();    
                    q2.pop_front();                
                }

                dp[d+j*v]=max(dp[d+j*v],q2.front()+j*w);
            }
        }
    }
    cout<<ans+dp[V];
    return 0;
}