• BZOJ 3163: [Heoi2013]Eden的新背包问题


    cdq+多重背包单调队列优化

    那个前缀后缀合并的是真的不靠谱(这明显T的啊)

    #include<cstdio>
    #include<algorithm>
    #include<vector>
    #define pr pair<int,int>
    #define mp make_pair
    #define fr first
    #define sc second
    using namespace std;
    int n,qe,m=1000,ans[300005],F[4005][1005],w[1005],v[1005],c[1005];
    vector<pr> vec[1005];
    struct node{
    	int fr,sc;
    }q[1005];
    void update(int t,int i){
    	for (int d=0; d<v[i]; d++){
    		int head=1,tail=0;
    		for (int j=0; v[i]*j+d<=m; j++){
    			int now=v[i]*j+d;
    			while (head<=tail && q[tail].sc<=F[t][now]-j*w[i]) tail--;
    			q[++tail]=(node){j,F[t][now]-j*w[i]};
    			while (head<=tail && q[head].fr<j-c[i]) head++;
    			F[t][now]=0;
    			if (head<=tail) F[t][now]=q[head].sc+j*w[i];
    		}
    	}
    }
    void solve(int t,int l,int r){
    	if (l==r){
    		for (int i=1; i<=m; i++) F[t][i]=max(F[t][i],F[t][i-1]);
    		for (int i=0; i<(int)vec[l].size(); i++) ans[vec[l][i].fr]=F[t][vec[l][i].sc];
    		return;
    	}
    	int mid=(l+r)>>1;
    	for (int i=0; i<=m; i++) F[t<<1][i]=F[t<<1|1][i]=F[t][i];
    	for (int i=mid+1; i<=r; i++) update(t<<1,i);
    	solve(t<<1,l,mid);
    	for (int i=l; i<=mid; i++) update(t<<1|1,i);
    	solve(t<<1|1,mid+1,r);
    }
    int main(){
    	scanf("%d",&n);
    	for (int i=1; i<=n; i++) scanf("%d%d%d",&v[i],&w[i],&c[i]);
    	scanf("%d",&qe);
    	for (int i=1; i<=qe; i++){
    		int x,y;
    		scanf("%d%d",&x,&y);
    		x++;
    		vec[x].push_back(mp(i,y));
    	}
    	solve(1,1,n);
    	for (int i=1; i<=qe; i++) printf("%d
    ",ans[i]);
    	return 0;
    }
    

      

  • 相关阅读:
    css3 @page
    Python:GUI
    Python: simple drawings
    JQuery 实现多个checkbox 只选中一个
    pgwSlideshow.js
    Html5: Drawing with text
    HTML5 Video player jQuery plugin
    cSharp:反射 Reflection
    机器学习基础---无监督学习之异常检测
    机器学习作业---主成分分析PCA
  • 原文地址:https://www.cnblogs.com/silenty/p/9917818.html
Copyright © 2020-2023  润新知