题目链接:Eden 的新背包问题
做一个前后缀背包,然后对每个答案预处理合并。
或者直接分治背包,由于比较无聊就写了第二种。复杂度多一个log,不过拓展性强。
AC代码:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=1e3+10;
int n,dp[N],res[N][N],q,m=1e3;
vector<pair<int,int> > v[N];
void calc(int l,int r){
for(int i=l;i<=r;i++) for(auto j:v[i]){
for(int k=m;k>=j.first;k--) dp[k]=max(dp[k],dp[k-j.first]+j.second);
}
}
void dfs(int l,int r){
if(l==r){memcpy(res[l],dp,sizeof dp); return ;}
int mid=l+r>>1,tmp[N];
memcpy(tmp,dp,sizeof dp); calc(mid+1,r);
dfs(l,mid); memcpy(dp,tmp,sizeof dp);
calc(l,mid); dfs(mid+1,r);
}
signed main(){
cin>>n;
for(int i=1,a,b,c;i<=n;i++){
cin>>a>>b>>c;
for(int j=1;j<=c;j*=2) v[i].push_back({a*j,b*j}),c-=j;
if(c) v[i].push_back({a*c,b*c});
}
dfs(1,n); cin>>q;
for(int i=1,x,y;i<=q;i++) scanf("%d %d",&x,&y),printf("%d\n",res[x+1][y]);
return 0;
}