bzoj4565 [HAOI2016] Character combination conclusion + state pressure + interval dp

If k==2, it is a record search,

But this question needs to enumerate k breakpoints if you use the idea of ​​searching for it.

So for enumeration breakpoints, there is likely to be optimization, for example, to a breakpoint, the optimal value of a decision

So consider the interval dp model, which is equivalent to inserting a number and then looking at the impact.

Then the merge is obviously from the insertion point to the other end point, so the interval can be enumerated from the insertion point to the other end point

Then the inserted point will be merged with the point on the left, so it can be pressed, only k bits are useful, and those greater than k will be merged

Then there is a very, very important potential condition that the interval is certain and the number of digits is certain;

So there is no need to distinguish between 000001 and a single 1


Code (note that the bzoj versions are connected together, other versions are not, this is other versions):

#include<iostream>
#include<cstdio> 
using namespace std;
#define N 305
int a[N],n,K,i,j,k,l,mb[N];
long long er[N],f[N][N][N],v[N],g[5],ans=-999999999999,len;
int main()
{
	scanf("%d%d",&n,&K);
	for(i=1;i<=n;i++)
	scanf("%d",&a[i]);
	er[0]=1;for(i=1;i<=9;i++)er[i]=er[i-1]*2;
	for(i=0;i<er[K];i++)
	{
		scanf("%d",&mb[i]);
		scanf("%lld",&v[i]);				
	}
	for(i=1;i<=n;i++)
	for(j=i;j<=n;j++)
	{
	for(k=0;k<er[K];k++)
	f[i][j][k]=-999999999999;
	}
	for(i=1;i<=n;i++)
	for(j=i;j>=1;j--)
	{
	if(i==j){f[i][j][a[i]]=0;continue;}
	for(k=i;k>j;k-=(K-1))
	{
		len=k-j;
	while(len>=K)len-=(K-1);	
	for(l=0;l<er[len];l++)
	{
	if(f[k][i][1]>=0)f[j][i][l<<1|1]=max(f[j][i][l<<1|1],f[j][k-1][l]+f[k][i][1]);		
	if(f[k][i][0]>=0)f[j][i][l<<1]=max(f[j][i][l<<1],f[j][k-1][l]+f[k][i][0]);		
	}
	}	
    if(K==1||((i-j)%(K-1)==0))//化而为一 
    {
    g[0]=g[1]=-999999999999;	
    	for(k=0;k<er[K];k++)
    	{
    		g[mb[k]]=max(g[mb[k]],f[j][i][k]+v[k]);
            f[j][i][k]=-999999999999;
		}
    f[j][i][1]=g[1];
	f[j][i][0]=g[0];   	
	}	
	}
		for(i=1;i<=n;i++)
	for(j=i;j<=n;j++)
	{
	for(k=0;k<er[K];k++)
		ans=max(f[i][j][k],ans);
	}
	printf("%lld",ans);
}


Guess you like

Origin blog.csdn.net/haobang866/article/details/79221690