「HEOI2013」Eden的新背包问题

Posted arextre

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了「HEOI2013」Eden的新背包问题相关的知识,希望对你有一定的参考价值。

题目

传送门

题解

假设我们忽略物品 (i),那么所有的物品我们分成 (1 ext{~}i-1) 的物品和 (i+1 ext{~}n) 的物品这两个部分,在这两个部分里面选择容量不超过 (e_i) 的物品的最大价值。

那么我们考虑从 (1) 开始跑部分背包,从 (n) 开始往前跑部分背包。

(dp1[i][j]) 为在物品 (1 ext{~}i) 中,选择容量不超过 (j) 的最大价值。

(dp2[i][j]) 为在物品 (i ext{~}n) 中,选择容量不超过 (j) 的最大价值。

这个应该是很好做的。

对于每一个询问我们有 (d,e),那么答案就是

[max{dp1[d-1][i]+dp2[d+1][e-i]mid 0le ile e} ]

#include<cstdio>

template<class T>inline T Max(const T x,const T y){return x>y?x:y;}
template<class T>inline T Min(const T x,const T y){return x<y?x:y;}
template<class T>inline T Fabs(const T x){return x>0?x:-x;}

const int MAXN=1e3;
const int MAXW=1e3;

int a[MAXN+5],b[MAXN+5],c[MAXN+5];

int dp1[MAXN+5][MAXW+5];
int dp2[MAXN+5][MAXW+5];

int n,q,d,e;

signed main(){
	scanf("%d",&n);
	for(int i=1;i<=n;++i)scanf("%d %d %d",&a[i],&b[i],&c[i]);
	for(int i=1;i<=n;++i)for(int k=0;k<=c[i];++k)for(int j=MAXW,siz=k*a[i];j>=siz;--j)
		dp1[i][j]=Max(dp1[i][j],dp1[i-1][j-k*a[i]]+k*b[i]);
	for(int i=n;i>=1;--i)for(int k=0;k<=c[i];++k)for(int j=MAXW,siz=k*a[i];j>=siz;--j)
		dp2[i][j]=Max(dp2[i][j],dp2[i+1][j-k*a[i]]+k*b[i]);
	scanf("%d",&q);
	while(q--){
		scanf("%d %d",&d,&e);++d;
		int ans=0;
		for(int i=0;i<=e;++i)ans=Max(ans,dp1[d-1][i]+dp2[d+1][e-i]);
		printf("%d
",ans);
	}
	return 0;
}

以上是关于「HEOI2013」Eden的新背包问题的主要内容,如果未能解决你的问题,请参考以下文章

Luogu P4095 [HEOI2013] Eden的新背包问题

BZOJ3163&Codevs1886: [Heoi2013]Eden的新背包问题[分治优化dp]

luogu P4095 [HEOI2013]Eden 的新背包问题 分治+背包dp

Luogu P4095 [HEOI2013]Eden 的新背包问题 思维/动规

JZOJ_3223. HBOI2013Ede的新背包问题 (Standard IO)

DSY3163*Eden的新背包问题