您的位置:首页 > 其它

【HBOI2013】Ede的新背包问题

2015-12-13 18:26 295 查看

题目



题意

就是给你一些物品,一些询问,每次询问要你求少了物品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])即可。

其实看起来很简单其实是很巧妙的。

[code]#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--;
    }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: