求助两遍DP只有55分

P4095 [HEOI2013] Eden 的新背包问题

```cpp /*Source:P4095. **Coder:NemonadePanda **Powered By Dev-Cpp*/ #include<bits/stdc++.h> using namespace std; const int N=1e3+5,M=12; int n,m,q,ban,tot,w[N*M],v[N*M]; int dp1[N*M][N],dp2[N*M][N],id[N*M]; struct Item{int w,v,c;}a[N]; inline void split(){ for(int i=1,t;i<=n;++i){ t=a[i].c; for(int j=1;j<=t;j*=2){ w[++tot]=a[i].w*j; v[tot]=a[i].v*j; t-=j,id[tot]=i; } if(t){ w[++tot]=a[i].w*t; v[tot]=a[i].v*t; id[tot]=i; } } return; } inline void DP(){ for(int i=1;i<=tot;++i){ for(int j=0;j<=1000;++j){ dp1[i][j]=dp1[i-1][j]; if(j-w[i]<0) continue; dp1[i][j]=max(dp1[i][j],dp1[i-1][j-w[i]]+v[i]); } } for(int i=tot;i>=1;--i){ for(int j=0;j<=1000;++j){ dp2[i][j]=dp2[i+1][j]; if(j-w[i]<0) continue; dp2[i][j]=max(dp2[i][j],dp2[i+1][j-w[i]]+v[i]); } } return; } signed main(){ scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%d%d%d", &a[i].w,&a[i].v,&a[i].c); scanf("%d",&q); split(); DP(); while(q--){ scanf("%d%d",&ban,&m);++ban; int res=0,l=0,r=0; while(id[l+1]<ban&&l<n) ++l; r=l; while(id[r+1]<=ban&&r<n) ++r; for(int i=0;i<=m;++i) res=max(res,dp1[l][i]+dp2[r+1][m-i]); printf("%d\n",res); } return 0; } /* 5 2 3 4 1 2 1 4 1 2 2 1 1 3 2 3 2 3 4 0 5 */ ```
by Nemonade @ 2023-05-27 15:13:54


@[NemonadePanda](/user/389797) 您的代码最后枚举 $l,r$ 时范围比 $tot$ 小就[过了](https://www.luogu.com.cn/record/111377570)
by 我是人999 @ 2023-05-27 15:42:03


``` while(id[l+1]<ban&&l<tot) ++l; ```
by 我是人999 @ 2023-05-27 15:42:40


@[我是人999](/user/311263) 谢谢
by Nemonade @ 2023-05-27 16:34:44


|