• 原题如下:

    Face The Right Way
    Time Limit: 2000MS   Memory Limit: 65536K
    Total Submissions: 6708   Accepted: 3124

    Description

    Farmer John has arranged his N (1 ≤ N ≤ 5,000) cows in a row and many of them are facing forward, like good cows. Some of them are facing backward, though, and he needs them all to face forward to make his life perfect.

    Fortunately, FJ recently bought an automatic cow turning machine. Since he purchased the discount model, it must be irrevocably preset to turn K (1 ≤ K ≤ N) cows at once, and it can only turn cows that are all standing next to each other in line. Each time the machine is used, it reverses the facing direction of a contiguous group of K cows in the line (one cannot use it on fewer than K cows, e.g., at the either end of the line of cows). Each cow remains in the same *location* as before, but ends up facing the *opposite direction*. A cow that starts out facing forward will be turned backward by the machine and vice-versa.

    Because FJ must pick a single, never-changing value of K, please help him determine the minimum value of K that minimizes the number of operations required by the machine to make all the cows face forward. Also determine M, the minimum number of machine operations required to get all the cows facing forward using that value of K.

    Input

    Line 1: A single integer: N 
    Lines 2..N+1: Line i+1 contains a single character, F or B, indicating whether cow i is facing forward or backward.

    Output

    Line 1: Two space-separated integers: K and M

    Sample Input

    7
    B
    B
    F
    B
    F
    B
    B

    Sample Output

    3 3

    Hint

    For K = 3, the machine must be operated three times: turn cows (1,2,3), (3,4,5), and finally (5,6,7)
  • 题解:对于一个特定的K如何求出让所有的牛面朝前方的最小操作次数?首先,交换区间反转的顺序对结果是没有影响的,另外,可以知道对同一个区间进行两次以上的反转是多余的,由此,问题就转化成了求需要反转的区间的集合。先考虑一下最左端的牛,因为包含这头牛的区间只有一个,所以如果这头牛面朝前方,我们就能知道这个区间不需要反转,反之如果这头牛面朝后方,对应的区间就必须进行反转了,而且在此之后的最左区间就再也不需要考虑了,这样一来通过首先考虑最左端的牛,问题的规模就缩小了1,不断地重复下去,就可以无需搜索求出最少所需反转次数了。通过前面的分析可以知道,忽略掉对同一个区间重复反转这类多余操作之后,只要存在让所有的牛都朝前的方法,那么操作就和顺序无关,可以唯一确定了。对于整个算法的话,我们需要对所有的K都求解一次,对于每个K最坏情况下需要进行N-K+1次的反转操作,每次操作又要反转K头牛,于是总的复杂度是O(N3)。区间反转的部分还可以进行优化,令f[i]:=区间[i,i+K-1]进行了反转的话为1,否则为0,这样在考虑第i头牛时,如果∑(j=i-K+1,i-1)f[j]为奇数的话,则这头牛的方向与起始方向是相反的,否则方向不变,由于∑(j=(i+1)-K+1,i)f[j] = ∑(j=i-K+1,i-1)f[j]+f[i]-f[i-K+1],所以这个和每一次都可以用常数时间计算出来,复杂度就降为了O(N2),就可以在时限内解决问题了。
  • 代码:
     #include <cstdio>
    #include <cctype>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    #define num s-'0' using namespace std; const int MAX_N=;
    const int INF=0x3f3f3f3f;
    int N;
    int dir[MAX_N], f[MAX_N]; void read(int &x){
    char s;
    x=;
    bool flag=;
    while(!isdigit(s=getchar()))
    (s=='-')&&(flag=true);
    for(x=num;isdigit(s=getchar());x=x*+num);
    (flag)&&(x=-x);
    } void write(int x)
    {
    if(x<)
    {
    putchar('-');
    x=-x;
    }
    if(x>)
    write(x/);
    putchar(x%+'');
    } int calc(int); int main()
    {
    read(N);
    for (int i=; i<N; i++)
    {
    char d;
    scanf("%c", &d);
    d=='B'? dir[i]=: dir[i]=;
    scanf("%c", &d);
    }
    int K=,M=N;
    for (int k=N; k>=; k--)
    {
    int m=calc(k);
    if (m>= && m<M)
    {
    M=m;
    K=k;
    }
    }
    write(K);putchar(' ');write(M);putchar('\n');
    } int calc(int K)
    {
    memset(f, , sizeof(f));
    int res=;
    int sum=;
    for (int i=; i<=N-K; i++)
    {
    if ((dir[i]+sum)% != )
    {
    res++;
    f[i]=;
    }
    sum+=f[i];
    if (i-K+>=) sum-=f[i-K+];
    }
    for (int i=N-K+; i<N; i++)
    {
    if ((dir[i]+sum)%!=) return -;
    if (i-K+>=) sum-=f[i-K+];
    }
    return res;
    }

Face The Right Way(POJ 3276)的更多相关文章

  1. 反转(开关问题) POJ 3276

    POJ 3276 题意:n头牛站成线,有朝前有朝后的的,然后每次可以选择大小为k的区间里的牛全部转向,会有一个最小操作m次使得它们全部面朝前方.问:求最小操作m,再此基础上求k. 题解:1.5000头 ...

  2. POJ 3276 (开关问题)

    题目链接: http://poj.org/problem?id=3276 题目大意:有一些牛,头要么朝前要么朝后,现在要求确定一个连续反转牛头的区间K,使得所有牛都朝前,且反转次数m尽可能小. 解题思 ...

  3. poj 3276(反转)

    传送门:Problem 3276 参考资料: [1]:挑战程序设计竞赛 先献上AC代码,题解晚上再补 题意: John有N头牛,这些牛有的头朝前("F"),有的朝后("B ...

  4. POJ 3276 Face The Right Way 反转

    大致题意:有n头牛,有些牛朝正面,有些牛朝背面.现在你能一次性反转k头牛(区间[i,i+k-1]),求使所有的牛都朝前的最小的反转次数,以及此时最小的k值. 首先,区间反转的顺序对结果没有影响,并且, ...

  5. Enum:Face The Right Way(POJ 3276)

    面朝大海,春暖花开 题目大意:农夫有一群牛,牛排成了一排,现在需要把这些牛都面向正确的方向,农夫买了一个机器,一次可以处理k只牛,现在问你怎么处理这些牛才可以使操作数最小? 这道题很有意思,其实这道题 ...

  6. POJ 3276

    Face The Right Way Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 2193   Accepted: 103 ...

  7. Face The Right Way 一道不错的尺取法和标记法题目。 poj 3276

    Face The Right Way Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 2899   Accepted: 133 ...

  8. POJ 3276 Face The Right Way 翻转(开关问题)

    题目:Click here 题意:n头牛排成一列,F表示牛面朝前方,B表示面朝后方,每次转向K头连续的牛的朝向,求让所有的牛都能面向前方需要的最少的操作次数M和对应的最小的K. 分析:一个区间反转偶数 ...

  9. POJ 3276 Face The Right Way

    Description Farmer John has arranged his N (1 ≤ N ≤ 5,000) cows in a row and many of them are facing ...

  10. POJ 3276 Face The Right Way(前缀和优化)

    题意:有长度为N的01串,有一个操作可以选择连续K个数字取反,求最小的操作数和最小的K使得最后变成全1串.(N<=5000) 由于K是不定的,无法高斯消元. 考虑枚举K,求出最小的操作数. 显然 ...

随机推荐

  1. STL函数库的应用第一弹——数据结构(队列)

    队列是什么? 队列是一种特殊的线性表,特殊之处在于它只允许在表的前端进行删除操作,而在表的后端进行插入操作. 和栈一样,队列是一种操作受限制的线性表.进行插入操作的端称为队尾,进行删除操作的端称为队头 ...

  2. 笔试算法稳了,GitHub 50k Star《labuladong的算法小抄》

    秋招算法有救了!!! 前不久在 GitHub 出现了一个手把手带你刷 LeetCode 的项目:fucking-algorithm. 该项目此前在 GitHub 开源后,连续多次霸榜 GitHub T ...

  3. offer收割机也有方法论

    秋招的战火就像这夏天的温度一样炙热,陆陆续续很多学弟学妹问我秋招的注意事项,作为温暖型大叔的我此刻必须出场了. 看仔细了,接下来龙叔就把这offer收割机的秘密都告诉你们. 如果你还没点关注的话,记得 ...

  4. 理解正向代理&反向代理

    通常的代理服务器,只用于代理内部网络对Internet的连接请求,客户机必须指定代理服务器,并将本来要直接发送到Web服务器上的http请求发送到代理服务器中.由于外部网络上的主机并不会配置并使用这个 ...

  5. 实现图像的二值化(java+opencv)

    书里的解释: 其他的没找到什么资料,直接参考百度百科 https://baike.baidu.com/item/%E5%9B%BE%E5%83%8F%E4%BA%8C%E5%80%BC%E5%8C%9 ...

  6. Dubbo源码学习之-通过源码看看dubbo对netty的使用

    前言 前段时间,从头开始将netty源码了解了个大概,但都是原理上理解.刚好博主对dubbo框架了解过一些,这次就以dubbo框架为例,详细看看dubbo这种出色的开源框架是如何使用netty的,又是 ...

  7. 牛客网PAT练兵场-完美数列

    题目地址:https://www.nowcoder.com/pat/6/problem/4056 题解:先将a数组进行排序,第一次按题意M<=n*p;n=a[0]时,M最大为J(如下图),然后n ...

  8. VMD的相关命令(转载)

    转载自:http://blog.sina.com.cn/s/blog_b48a7ac30102w6xg.html 自我学习总结: 1.打开VMD main上Extensions中的TkConsole这 ...

  9. OI常用数学定理&方法总结

    组合数计算($O(n)$) https://www.cnblogs.com/linzhuohang/p/11548813.html Lucas定理 如果要计算很大的组合数,但模数较小,考虑这个方法 对 ...

  10. Docker 之常见应用部署

    本文教大家如何将常见的应用使用 Docker 进行部署,巩固大家 Docker 命令的学习,下文教大家如何构建属于我们自己的 Docker 镜像. Tomcat 拉取镜像. docker pull t ...