题目
题意
就是给你一些物品,一些询问,每次询问要你求少了物品x,时钱为y的最大价值。
分析
其实也就是其他的物品组成y的最大价值。
于是我们可以先预处理出f[i,j],为前i个物品,用了j钱的最大价值,
同理我们再预处理出g[i,j],为i到n个物品,用了j钱的最大价值。
于是对于每次询问,我们可以枚举z,求max(f[x-1,z]+g[x+1,y-z])即可。
其实看起来很简单其实是很巧妙的。
#include<cstdio>
#include<cmath>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const int N=1005;
int n,a[N],b[N],c[N],x,y,f[N][N],g[N][N],q,l,ans;
int main(){
scanf("%d",&n);
fo(i,1,n) scanf("%d%d%d",&a[i],&b[i],&c[i]);
fo(i,1,n)
fd(j,1000,0) {
f[i][j]=f[i-1][j];
fo(k,1,c[i])
if (j>=k*a[i]) f[i][j]=max(f[i][j],f[i-1][j-k*a[i]]+k*b[i]);
else break;
}
fd(i,n,1)
fd(j,1000,0) {
g[i][j]=g[i+1][j];
fo(k,1,c[i])
if (j>=k*a[i]) g[i][j]=max(g[i][j],g[i+1][j-k*a[i]]+k*b[i]);
else break;
}
scanf("%d",&q);
while (q) {
scanf("%d%d",&x,&y);ans=0;
fo(i,0,y) ans=max(ans,f[x][y-i]+g[x+2][i]);
printf("%d\n",ans);q--;
}
}