poj 3276 Face The Right Way

Posted 罚时自动机

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj 3276 Face The Right Way相关的知识,希望对你有一定的参考价值。

题意:有N头顺序排列的牛,有的头朝前,有的朝后,现在有一台机器,可以设置每次翻转连续的k头牛,求最小的的翻转次数m

分析:一头牛翻转两次=不翻转,也就是说一头牛要么翻转,要么不翻转,那么枚举k,然后模拟求翻转的次数,这样的话,O(n^3),超时,根据尺取法的思想,我们依次观察每头牛是否翻转,f[i]表示i是否翻转

那么对于j来说,(j-k+1)~(j-1) 的f的和就是j在前面被翻转的次数,sum+dir[j]为偶,不翻转,否则,翻转,对于出了框子的牛,sum-f[i-k+1],

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=5005;
int dir[maxn],f[maxn],n;

int solve(int k){
    memset(f,0,sizeof(f));
    int sum=0,ans=0;
    for(int i=0;i+k<=n;i++){
        if((sum+dir[i])%2!=0){
            ans++;
            f[i]=1;
        }
        sum+=f[i];
        if(i-k+1>=0)
          sum-=f[i-k+1];
    }
    for(int i=n-k+1;i<n;i++){
      if((sum+dir[i])%2!=0)
        return -1;
      if(i-k+1>=0)
        sum-=f[i-k+1];
    }
    return ans;
}

int main(){
    while(~scanf("%d",&n)){
        getchar();
        char c;
        for(int i=0;i<n;i++){
            c=getchar();getchar();
            if(c==\'B\')
              dir[i]=1;
            else
              dir[i]=0;
        }
        int K=1,M=n;
        for(int k=1;k<=n;k++){
            int m=solve(k);
            if(m>=0&&M>m){
                M=m;
                K=k;
            }
        }
        printf("%d %d\\n",K,M);
    }
    return 0;
}
View Code

 

以上是关于poj 3276 Face The Right Way的主要内容,如果未能解决你的问题,请参考以下文章

POJ - 3276 Face The Right Way

Face The Right Way(POJ 3276)

POJ3276 Face The Right Way (尺取法)

POJ 3276 Face The Right Way 开关问题

poj3276 Face The Right Way

poj3276 Face The Right Way