码迷,mamicode.com
首页 > 其他好文 > 详细

poj 3276 Face The Right Way

时间:2016-06-09 09:41:48      阅读:176      评论:0      收藏:0      [点我收藏+]

标签:

题意:有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

标签:

原文地址:http://www.cnblogs.com/jihe/p/5571944.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!