CF Global Round 10-D
D.Omkar and Bed Wars
\(Description:\)
\(n\)个人站成一个圈,\(i\)的右边是\(i+1\),\(n\)的右边是\(1\)。他们初始有一个朝向(朝左/右)。每次操作可以让一个人转向(左变右或相反)。要求不出现连续三个朝左或连续三个朝右的人,求最小操作数
\(Solution:\)
经典\(dp\),令\(f[i][a][b][c][d]\)为从第一个到第\(i\)个人,前两个状态为\(a\)和\(b\),后两个人状态为\(c\)和\(d\)的最小修改次数
转移时要遍历最后三位,保证后三位不一样
最后的答案为首尾相接后没有连续三个相同的状态的最小值
\(Code:\)
#include<bits/stdc++.h>
#define inf (200005)
using namespace std;
typedef long long lol;
const int N=200005;
int t,n,o[N],f[N][2][2][2][2];
char s[N];
int main(){
scanf("%d",&t);
while(t--){
scanf("%d%s",&n,s+1);
for(int i=1;i<=n;i++)o[i]=s[i]=='R';
for(int i=1;i<=n;i++)
for(int a=0;a<=1;a++)
for(int b=0;b<=1;b++)
for(int c=0;c<=1;c++)
for(int d=0;d<=1;d++)
f[i][a][b][c][d]=inf;
for(int a=0;a<=1;a++)
for(int b=0;b<=1;b++)
f[2][a][b][a][b]=(o[1]!=a)+(o[2]!=b);
for(int i=3;i<=n;i++)
for(int a=0;a<=1;a++)
for(int b=0;b<=1;b++)
for(int c=0;c<=1;c++)
for(int d=0;d<=1;d++)
for(int e=0;e<=1;e++)
if(!(c==d&&d==e)){
f[i][a][b][d][e]=min(f[i][a][b][d][e],f[i-1][a][b][c][d]+(e!=o[i]));
}
int ans=inf;
for(int a=0;a<=1;a++)
for(int b=0;b<=1;b++)
for(int c=0;c<=1;c++)
for(int d=0;d<=1;d++)
if(!(c==d&&d==a)&&!(d==a&&a==b))
ans=min(ans,f[n][a][b][c][d]);
printf("%d\n",ans);
}
return 0;
}
标签:
动态规划
, codeforces
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】博客园携手 AI 驱动开发工具商 Chat2DB 推出联合终身会员
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个超经典 WinForm,WPF 卡死问题的终极反思
· ASP.NET Core - 日志记录系统(二)
· .NET 依赖注入中的 Captive Dependency
· .NET Core 对象分配(Alloc)底层原理浅谈
· 聊一聊 C#异步 任务延续的三种底层玩法
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(一):从.NET IoT入
· .NET 开发的分流抢票软件,不做广告、不收集隐私
· ASP.NET Core - 日志记录系统(二)
· 一个超经典 WinForm,WPF 卡死问题的终极反思
· 实现windows下简单的自动化窗口管理