• 旅行商的背包


    洛咕

    题意:有(n)种物品,第(i)种体积为(V_i),价值为(W_i),共有(D_i)件.的背包体积是(C).还有m件奇货,第(i)件的价值(Y_i)与分配的体积(X_i)之间的关系为(Y_i=a_i*X_i^2+b_i*X_i+c_i).求最大价值.(1≤n,C≤10000,1≤m≤5,1≤Wi,Vi,Di≤1000,-1000≤ai,bi,ci≤1000.)

    分析:前面n种物品是多重背包来做,二进制优化或者单调队列优化都可以.后面m件物品是完全背包,直接枚举分配的体积就好了.

    无力吐槽这道题.自己的单调队列优化多重背包怎么都T两个点,别人的跑得飞快.

    把自己的辣鸡80分代码也挂出来吧,希望引以为戒.

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<map>
    #include<set>
    #define ll long long
    #define rg register
    using namespace std;
    inline int read(){
        rg int x=0,o=1;char ch=getchar();
        while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
        if(ch=='-')o=-1,ch=getchar();
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x*o;
    }
    const int N=10005;
    int q[N],f[2][N];
    inline int maxx(int a,int b){if(a>b)return a;return b;}
    int main(){
    	rg int n=read(),m=read(),C=read();
    	for(rg int i=1;i<=n;++i){
    		rg int v=read(),w=read(),d=read();
    		for(rg int j=0;j<v;++j){
    			rg int l=1,r=0;
    			for(rg int k=j;k<=C;k+=v){
    				while(l<=r&&k-q[l]>v*d)++l;
    				while(l<=r&&f[(i-1)&1][q[r]]-q[r]/v*w<f[(i-1)&1][k]-k/v*w)--r;
    				q[++r]=k;
    				f[i&1][k]=f[(i-1)&1][q[l]]+(k-q[l])/v*w;
    			}
    		}
    	}
    	for(rg int i=1;i<=m;++i){
    		rg int a=read(),b=read(),c=read();
    		for(rg int j=C;j>=0;--j)
    			for(rg int k=0;k<=j;++k)
    				f[n&1][j]=maxx(f[n&1][j],f[n&1][j-k]+a*k*k+b*k+c);		
    	}
    	printf("%d
    ",f[n&1][C]);
        return 0;
    }
    

    题解代码

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<map>
    #include<set>
    #define ll long long
    #define rg register
    using namespace std;
    inline int read(){
        rg int x=0,o=1;char ch=getchar();
        while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
        if(ch=='-')o=-1,ch=getchar();
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x*o;
    }
    const int N=1e4+5;
    int dp[N],f[N],q[N];
    int main(){
    	rg int n=read(),m=read(),C=read();
    	for(rg int i=1;i<=n;++i){
    		rg int v=read(),w=read(),d=read();
    		for(rg int j=0;j<v;++j){
    			rg int l=1,r=0;
    			for(rg int k=0;k*v+j<=C;++k){
    				rg int x=dp[k*v+j]-k*w;
    				while(l<=r&&x>f[r])--r;
    				q[++r]=k;f[r]=x;
    				if(q[l]+d<k)++l;
    				dp[k*v+j]=f[l]+k*w;
    			}
    		}
    	}
    	for(rg int i=1;i<=m;++i){
    		rg int a=read(),b=read(),c=read();
    		for(rg int j=C;j>=0;--j)
    			for(rg int k=0;k<=j;++k)
    				if(dp[j-k]+(a*k+b)*k+c>dp[j])dp[j]=dp[j-k]+(a*k+b)*k+c;
    	}
    	printf("%d
    ",dp[C]);
        return 0;
    }
    
    
  • 相关阅读:
    树形dp(HDU1520)
    POJ3071(概率DP)
    网络流之FF算法(poj1273&&洛谷P3376)
    二分图匹配之匈牙利算法
    江西财经大学第二届程序设计竞赛——E
    浅谈数位dp
    浅谈数位dp——hdu 不要62
    buns~~~一个简单的背包问题
    POJ 1066 Treasure Hunt (线段相交)
    POJ 2653 Pick-up sticks (线段相交)
  • 原文地址:https://www.cnblogs.com/PPXppx/p/11537336.html
Copyright © 2020-2023  润新知