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

Posted jackpei

tags:

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

当时一直在想前缀和。。。多亏张队提醒。。。


 

从1到n背次包,保存每一个状态下的价值,就是不要把第一维压掉;再从n到1背一次,同样记住每种状态;

然后询问时相当于是max(前缀+后缀),当然前缀后缀中间去掉了一个应去掉的商品。

#include<cstdio>
#include<iostream>
#define R register int
using namespace std;
inline int g() {
    R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch==-?-1:fix;
    do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix;
}
int n,q;
int a[1010],b[1010],c[1010],f[1010][1010],h[1010][1010];
signed main() {
    n=g();
    for(R i=1;i<=n;++i) a[i]=g(),b[i]=g(),c[i]=g();
    for(R i=1;i<=n;++i) for(R j=1000;j>=0;--j) {
        f[i][j]=f[i-1][j];
        for(R k=1;k<=c[i];++k) if(j>=k*a[i]) f[i][j]=max(f[i][j],f[i-1][j-k*a[i]]+k*b[i]);
        else break;
    }
    for(R i=n;i>=1;--i) for(R j=1000;j>=0;--j) {
        h[i][j]=h[i+1][j];
        for(R k=1;k<=c[i];++k) if(j>=k*a[i]) h[i][j]=max(h[i][j],h[i+1][j-k*a[i]]+k*b[i]);
        else break;
    } q=g();
    for(R i=1;i<=q;++i) {
        R k=g(),w=g(); R ans=0;
        for(R i=0;i<=w;++i) ans=max(ans,f[k][w-i]+h[k+2][i]); 
        printf("%d\n",ans);
    }
}

2019.04.25

以上是关于Luogu P4095 [HEOI2013]Eden 的新背包问题 思维/动规的主要内容,如果未能解决你的问题,请参考以下文章

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

luogu P4097 [HEOI2013]Segment

[HEOI2013]Segment

P4097 [HEOI2013]Segment(李超树)

[Luogu 4092] HEOI/TJOI2016 树

luogu P2825 [HEOI2016/TJOI2016]游戏