题目意思就是给你n头牛,有向前有向后的,每次你可以把连续的k头牛反向,问最少要几次操作才能使得牛全部向前,并且在 操作最小的情况下,k最小是多少。
解答,o(n)的复杂度去检查在k一定的情况下最小的操作数,从左往右检查,如果反向则操作一次,用ret来标记每个点被操作的次数,一边扫一边更新ret,就可以o(1)的检查每个点的状态。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=5e4+9;
char a[maxn];
int n,ans,ansk;
int dp[maxn];
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
getchar();
scanf("%c",&a[i]);
}
ans=maxn;
for(int k=1;k<=n;k++)
{
memset(dp,0,sizeof(dp));
int ret=0,sum=0,flag=1;
for(int i=1;i<=n;i++)
{
if(i-k>=1)
ret-=dp[i-k];
if(i<=n-k+1)
{
if((ret%2==0&&a[i]=='B')||(ret%2==1&&a[i]=='F'))
{
sum++;
dp[i]=1;
ret++;
}
}
else
{
if((ret%2==0&&a[i]=='B')||(ret%2==1&&a[i]=='F'))
{
flag=0;
break;
}
}
}
if(flag&&sum<ans)
{
ans=sum;
ansk=k;
}
}
printf("%d %d\n",ansk,ans);
return 0;
}
本文介绍了一种通过翻转牛群中连续的牛的方向来使所有牛朝同一方向前进的算法。采用O(n)的时间复杂度扫描整个牛群,记录每头牛的操作次数并寻找最优解。最终确定最小的操作次数及对应的最小翻转长度。
466

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



