洛谷P4852

f[i][j][0/1]表示用了i次连抽,j次单抽且结尾是连抽/单抽的最大价值

f[i][j][0]=max(f[i1][j][0],f[i1][j][1])+aic+jc+1

f[i][j][1]=max(f[i][jk][0]+sumic+jsumic+jk)

其中1<=k<=dsum是前缀和数组

这两个方程浅显易懂,读者很容易模拟出来,就不再赘述了

直接进入正题:用单调队列优化此方程

第一个方程显然是O(1)的,不用优化

对于第二个方程,改写成

f[i][j][1]=max(f[i][jk][0]sumic+jk)+sumic+j

容易发现这是单调队列优化的经典形式,就做完了。

时间复杂度O(nm)

实际上这种分离变量使不同的变量相互隔开的做法非常常见,建议读者在做一下这道题,感受方程是如何变化的。

code

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=45,M=80010,C=3010;
int n,m,c,d;
int a[N*C+M],sum[N*C+M];
struct Node
{
	int pos,val;
}temp,q[M];
struct node
{
	int x,y,z;
}pre[N][M][2];
ll f[N][M][2];
int read()
{
    int x=0,f=1;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-f;s=getchar();}
    while(s>='0'&&s<='9'){x=x*10+s-48;s=getchar();}
    return x*f;
}
void print(int x,int y,int z)
{
	if(!x) return;
	print(pre[x][y][z].x,pre[x][y][z].y,pre[x][y][z].z);
	if(!z) printf("%d ",x*c+y-c+1);
}
int main() 
{
	n=read(),m=read(),c=read(),d=read();
	for(int i=1;i<=c*n+m;i++)
	{
		a[i]=read();
		sum[i]=sum[i-1]+a[i];
	}
	memset(f,-0x3f,sizeof(f));
	for(int i=1;i<=d;i++) f[0][i][1]=sum[i];
	for(int i=1;i<=n;i++)
	for(int j=0,l=1,r=0;j<=m;j++)
	{
		if(i>0) 
		{
		    if(i==1&&j==0) f[i][j][0]=a[1];
		    else f[i][j][0]=max(f[i-1][j][0],f[i-1][j][1])+a[(i-1)*c+j+1];
			pre[i][j][0].x=i-1,pre[i][j][0].y=j;
			if(f[i-1][j][0]>f[i-1][j][1]) pre[i][j][0].z=0;
			else pre[i][j][0].z=1;
		}
		if(j>0)
		{
			while(l<=r&&q[l].pos<j-d) l++;
			if(l<=r) f[i][j][1]=q[l].val+sum[i*c+j];
			pre[i][j][1].x=i,pre[i][j][1].y=q[l].pos,pre[i][j][1].z=0;
			temp.pos=j,temp.val=f[i][j][0]-sum[i*c+j];
			while(l<=r&&q[r].val<=temp.val) r--;
			q[++r]=temp;
		}
		else
		{
		    temp.pos=0,temp.val=f[i][0][0]-sum[i*c];
		    q[++r]=temp;
		}
	} 
	printf("%lld\n",max(f[n][m][0],f[n][m][1]));
    if(f[n][m][0]>f[n][m][1]) print(n,m,0);
	else print(n,m,1);
	return 0;
}

另外一个小插曲,我数组asum的大小一开始开的N然后乱WA(是的,并不是RE),直接导致我多调3小时。wtcl

谢谢阅读

posted @   最爱丁珰  阅读(27)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示