蒟蒻求助
查看原帖
蒟蒻求助
159959
虫洞吞噬者楼主2021/10/10 22:00

RT,大致思路就是二进制优化+正反跑两遍背包然后再排除限制物品后统计答案,结果只有55分QAQ

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define int long long
int n,m,q,ans=-1,cnt,maxn=-1;
int li[1001000],mm[1001000];
int f1[100002][1002],f2[100002][1002];
struct node{
	int id,cos,w;
}num[500100];
signed main()
{
	scanf("%lld",&n);
	for(int i=1;i<=n;++i)
	{
		int a,b,c;
		scanf("%lld%lld%lld",&a,&b,&c);
		int bas=1;
		while(c)
		{
			++cnt;
			if(c>=bas)
			{
				c-=bas;
				num[cnt].id=i;
				num[cnt].cos=a*bas;
				num[cnt].w=b*bas;
			}
			else
			{
				num[cnt].id=i;
				num[cnt].cos=a*c;
				num[cnt].w=b*c;
				c=0;
			}
			bas*=2;
		}
	}
	scanf("%lld",&q);
	for(int i=1;i<=q;++i)
	{
		scanf("%lld%lld",&li[i],&mm[i]);
		maxn=max(maxn,mm[i]);
	}
	for(int i=1;i<=cnt;++i)
	{
		for(register int j=0;j<=maxn;++j)f1[i][j]=f1[i-1][j];
		for(register int j=maxn;j>=num[i].cos;--j)
			f1[i][j]=max(f1[i][j],f1[i-1][j-num[i].cos]+num[i].w);
	}
	for(int i=cnt;i>=1;--i)
	{
		for(register int j=0;j<=maxn;++j)f2[i][j]=f2[i+1][j];
		for(register int j=maxn;j>=num[i].cos;--j)
			f2[i][j]=max(f2[i][j],f2[i+1][j-num[i].cos]+num[i].w);
	}
	for(int i=1;i<=q;++i)
	{
		int l=0,r=0,cur=li[i]+1;m=mm[i];
		while(num[l+1].id<cur&&l<n)++l;
		r=l;
		while(num[r+1].id<=cur&&r<n)++r;
		ans=-1;
		for(register int j=0;j<=m;++j)
			ans=max(ans,f1[l][j]+f2[r+1][m-j]);
		printf("%lld\n",ans);
	}
	return 0;
}
2021/10/10 22:00
加载中...