标签:class 一个 背包问题 line ++i fabs 价值 math --
假设我们忽略物品 \(i\),那么所有的物品我们分成 \(1\text{~}i-1\) 的物品和 \(i+1\text{~}n\) 的物品这两个部分,在这两个部分里面选择容量不超过 \(e_i\) 的物品的最大价值。
那么我们考虑从 \(1\) 开始跑部分背包,从 \(n\) 开始往前跑部分背包。
设 \(dp1[i][j]\) 为在物品 \(1\text{~}i\) 中,选择容量不超过 \(j\) 的最大价值。
设 \(dp2[i][j]\) 为在物品 \(i\text{~}n\) 中,选择容量不超过 \(j\) 的最大价值。
这个应该是很好做的。
对于每一个询问我们有 \(d,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\n",ans);
}
return 0;
}
标签:class 一个 背包问题 line ++i fabs 价值 math --
原文地址:https://www.cnblogs.com/Arextre/p/12766635.html