【bzoj1704】[Usaco2007 Mar]Face The Right Way 自动转身机 贪心

题目描述

农夫约翰有N(1≤N≤5000)只牛站成一排,有一些很乖的牛朝前站着.但是有些不乖的牛却朝后站着.农夫约翰需要让所有的牛都朝前站着.幸运的是约翰最近买了一个自动转身机.这个神奇的机器能使K(1≤K≤N)只连续的牛转身.  因为约翰从来都不改变K的价值,请帮助他求出K,使旋转次数M达到最小.同时要求出对应的M.

输入

第1行:整数N.
第2行到第N+1行:第i+l行表示牛j的朝向,F表示朝前,B表示朝后.

输出

一行两个数,分别是K和M,中间用空格隔开

样例输入

7
B
B
F
B
F
B
B

样例输出

3 3


题解

贪心,应该不太难想。

先枚举k,然后贪心判断能否全部转过来。每次找到一个,如果没转过来,那么把从它开始连续的k个转过来。如果不够k个,说明不成立。

转的过程需要用到差分数组,注意细节。

#include <cstdio>
#include <cstring>
int v[5001] , r[5001];
char str[5];
int main()
{
    int n , i , j , k , minm = 0x7fffffff , rev , flag , m;
    scanf("%d" , &n);
    for(i = 1 ; i <= n ; i ++ )
        scanf("%s" , str) , v[i] = (str[0] != 'F');
    for(i = 1 ; i <= n ; i ++ )
    {
        rev = 0 , flag = 1 , m = 0;
        memset(r , 0 , sizeof(r));
        for(j = 1 ; j <= n ; j ++ )
        {
            if(v[j] ^ rev)
            {
                if(i + j - 1 > n)
                {
                    flag = 0;
                    break;
                }
                r[j] ^= 1 , r[i + j - 1] ^= 1;
                m ++ ;
            }
            rev ^= r[j];
        }
        if(flag && minm > m)
            minm = m , k = i;
    }
    printf("%d %d
" , k , minm);
    return 0;
}
原文地址:https://www.cnblogs.com/GXZlegend/p/6305675.html