Eden 的新背包问题

题目链接: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;
}

猜你喜欢

转载自blog.csdn.net/weixin_43826249/article/details/107851633