题解【AtCoder - CODE FESTIVAL 2017 qual B - D - 101 to 010】

题目:https://atcoder.jp/contests/code-festival-2017-qualb/tasks/code_festival_2017_qualb_d

题意:给一个 01 串,每次可以把 101 换成 010,问最多能换多少次 .

题解:

dpi 表示 1i 最多换多少次,记录一个 li 表示 i 左边最接近的 0ri 表示 i 右边最接近的 0,从而:

dpi=max{dpi1dpli3+1+ili33i3si3,si2,si1101(1)dpli3+2+ili34(1)li3i4

dpli3=max{dpi+li3i2i+3nsi,si+1,si+2101(2)}

dpli31=max{dpi+li3i3(2)li3i+3}

对于每一行的解释:

  • 第一行:显然
  • 第二行:若目前有 101,则换
  • 第三行:若换完还有 101,再换
  • 第四、五行:同第二、三行 .

Code:

using namespace std;
const int N=500500;
int n,dp[N],l[N],r[N];
string s;
int main()
{
	scanf("%d",&n); cin>>s;
	l[0]=(s[0]=='0'?0:-1); r[n]=n;
	for (int i=1;i<n;i++)
		if (s[i]=='1') l[i]=l[i-1];
		else l[i]=i;
	for (int i=n-1;i>=0;i--)
		if (s[i]=='1') r[i]=r[i+1];
		else r[i]=i;
	for (int i=0;i<=n;i++)
	{
		if (i) dp[i]=max(dp[i],dp[i-1]); // because line 47 .
		if ((i>=3)&&(s[i-1]=='1')&&(s[i-2]=='0')&&(s[i-3]=='1')) // pre
		{
			int j=l[i-3];
			dp[i]=max(dp[i],dp[j+1]+i-j-3);
			if (j!=i-4) dp[i]=max(dp[i],dp[j+2]+i-j-4); // 101 * 2
		}
		if ((i+3<=n)&&(s[i]=='1')&&(s[i+1]=='0')&&(s[i+2]=='1')) // suc ( nxt )
		{
			int j=r[i+2];
			dp[j]=max(dp[j],dp[i]+j-i-2);
			if (j!=i+3) dp[j-1]=max(dp[j-1],dp[i]+j-i-3); // 101 * 2;
		}
	} printf("%d",dp[n]);
	return 0;
}
posted @   yspm  阅读(85)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
😅​
点击右上角即可分享
微信分享提示