您的位置:首页 > 其它

poj 3276 Face The Right Way

2016-06-09 08:42 274 查看
题意:有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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: