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


 

从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

相关文章:

  • 2022-01-03
  • 2022-01-10
  • 2022-12-23
  • 2021-08-21
  • 2021-10-09
  • 2021-12-18
  • 2022-02-07
  • 2022-02-07
猜你喜欢
  • 2021-11-03
  • 2021-08-25
  • 2021-12-06
  • 2022-12-23
  • 2021-12-03
  • 2022-02-20
  • 2021-05-22
相关资源
相似解决方案