洛谷P4852

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

\(f[i][j][0]=max(f[i-1][j][0],f[i-1][j][1])+a_{i*c+j-c+1}\)

\(f[i][j][1]=max(f[i][j-k][0]+sum_{i*c+j}-sum_{i*c+j-k})\)

其中\(1<=k<=d\)\(sum\)是前缀和数组

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

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

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

对于第二个方程,改写成

\(f[i][j][1]=max(f[i][j-k][0]-sum_{i*c+j-k})+sum_{i*c+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;
}

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

谢谢阅读

posted @ 2021-10-03 17:56  最爱丁珰  阅读(23)  评论(0编辑  收藏  举报