ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[HAOI2016]字符合并

2022-02-18 16:05:16  阅读:195  来源: 互联网

标签:tmp 字符 le int 32 合并 HAOI2016 260 区间


一个长为 \(1\le n\le 300\) 的 01 串 \(a\),可以选长为 \(2\le k\le 8\) 的连续段 \([l,r]\) 替换为 \(c_x\in \{0,1\}\),得到 \(1\le w_x\le 10^9\) 价值,其中 \(x\) 表示 \(a:[l,r]\) 构成的二进制数。例如 10011 将中间三个字符替换为 1,会得到新字符串 111,而后续的操作均在新字符串上进行。

受到启发

  • 看到 \(k\le 8\) 想到状态压缩。
  • 看到 \(n\le 300\) 想到区间 dp。

观察性质

  • 将一个区间从始态到终态的过程本质是将区间划分成 \(<k\) 段,每一段中的数合并成一个数。
  • 由于 \(w_x\le 1\),对于一固定长度区间,它最后的长度是确定的,因一次操作将区间长削减 \(k-1\)。为 y=len%(k-1)==0?(k-1):len%(k-1)

题解

\(f[l,r,s]\) 表示区间 \([l,r]\) 的终态为 \(s\) 的最大价值。\(s\) 是一个 y 位二进制数,y 的含义见上。
枚举 \(s\) 的最后一位所代表的区间后缀的起始点 \(i>l\),\(f[l,r,s]=f[l,i-1,s>>1]+f[i,r,s\&1]\)。
\(O(n^32^y)\le O(n^32^k)\)。

观察到有效地 \(i\) 只可能是 \(r,r-(k-1),r-2(k-1),...\),这样枚举可将常数 \(\div k\)。
\(O(n^32^k/k)\)。区间 dp 常数小,可通过。

一些注意事项:

  1. LL
  2. 枚举 \(s\) 时,如果 y==1,发现没法转移。考虑倒数第二次转移的末态作为 \(s\) 来。即 y+=(k-1)。但储存 f[l,r,s] 时的 \(s\) 还是得按最后一次的 \(s\) 来表示。
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=305;
int n,k,ans,a[N],c[260],v[260],f[N][N][260];
signed main(){
	cin>>n>>k;
	for(int i=1;i<=n;i++)cin>>a[i];
	for(int i=0;i<(1<<k);i++)cin>>c[i]>>v[i];
	memset(f,-0x3f,sizeof(f));
	for(int i=1;i<=n;i++)f[i][i][a[i]]=0;
	for(int l=1;l+k-1<=n;l++){
		int x=0;
		for(int i=l;i<=l+k-1;i++)x=(x<<1)+a[i];
		f[l][l+k-1][c[x]]=v[x];
	}
	for(int len=2;len<=n;len++){
		for(int l=1,r=len;r<=n;l++,r++){
			int x=len%(k-1);if(!x)x+=k-1;if(x<=1)x+=k-1;
			for(int s=0;s<(1<<x);s++){
				int _s=x==k?c[s]:s;
				int tmp=f[0][0][0];
				for(int i=r;i>l;i-=k-1)
					if(f[l][i-1][s>>1]!=f[0][0][0]&&f[i][r][s&1]!=f[0][0][0])
						tmp=max(tmp,f[l][i-1][s>>1]+f[i][r][s&1]);
				if(x==k&&tmp!=f[0][0][0])tmp+=v[s];
				f[l][r][_s]=max(f[l][r][_s],tmp);
				if(len==n)ans=max(ans,f[l][r][_s]);
			}
		}
	}
	cout<<ans;
}

标签:tmp,字符,le,int,32,合并,HAOI2016,260,区间
来源: https://www.cnblogs.com/impyl/p/15909002.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有