poj 3276 Face The Right Way

题目意思就是给你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;
}

你可能感兴趣的:(poj 3276 Face The Right Way)