【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个,说明不成立。

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#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\n" , k , minm);
    return 0;
}
posted @   GXZlegend  阅读(343)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示