https://codeforces.com/contest/1476/problem/D
观察发现向一个方向就一直直走就行了
然后把dp[i][j%2][k]表示第j填在i位置向k方向走,把这个dp数组用记忆化搜索处理出来就行了
ans[i]就是向左走向右走加起来
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxl=3e5+10;
int n,m,k,tot,cnt;
int a[maxl],ans[maxl];
int dp[maxl][2][2];
char s[maxl];
bool vis[maxl];
inline void prework()
{
scanf("%d",&n);
scanf("%s",s+1);
for(int i=1;i<=n;i++)
if(s[i]=='R')
a[i]=1;
else a[i]=0;
for(int i=0;i<=n;i++)
for(int j=0;j<2;j++)
for(int k=0;k<2;k++)
dp[i][j][k]=-1;
}
inline int dfs(int i,int j,int k)
{
if(dp[i][j][k]>=0)
return dp[i][j][k];
if(k==1 && i==n)
{
dp[i][j][k]=1;
return 1;
}
if(k==0 && i==0)
{
dp[i][j][k]=1;
return 1;
}
if(k==1)
{
if((a[i+1]^j)!=1)
dp[i][j][k]=1;
else
dp[i][j][k]=1+dfs(i+1,j^1,k);
}
else
{
if((a[i]^j)!=0)
dp[i][j][k]=1;
else
dp[i][j][k]=1+dfs(i-1,j^1,k);
}
return dp[i][j][k];
}
inline void mainwork()
{
int nul;
for(int i=0;i<=n;i++)
{
for(int j=0;j<2;j++)
for(int k=0;k<2;k++)
if(dp[i][j][k]<0)
nul=dfs(i,j,k);
ans[i]=dp[i][0][1]+dp[i][0][0]-1;
}
}
inline void print()
{
for(int i=0;i<=n;i++)
printf("%d%c",ans[i]," \n"[i==n]);
}
int main()
{
int t=1;
scanf("%d",&t);
while(t--)
{
prework();
mainwork();
print();
}
return 0;
}
该博客主要讨论了一个关于字符串中字符行走的问题,通过动态规划(dp)策略进行求解。作者实现了一个记忆化搜索的解决方案,计算了从不同位置向左右两个方向行走的最优路径。代码中定义了dp数组来存储状态,并给出了完整的C++代码实现。
1078

被折叠的 条评论
为什么被折叠?



