题意:n头牛,不是朝前就是朝后,操作一次可以使连续k头牛反转。求最小操作次数,使所有牛朝前,且k尽量小。
思路:枚举k=1~n。判断取当前的k是否可行,如果可行需要操作多少次。判断方法是累计区间内反转次数,然后检查最后的k头牛是否朝前。
#include<iostream>
#include<cmath>
#include<queue>
#include<vector>
#include<algorithm>
#include<string.h>
#include<cstdio>
using namespace std;
int a[5010];
int n;
int f[5010];
int calc(int k){
int cnt=0;
for(int i=1;i<=n;i++)f[i]=0;
int ans=0;
for(int i=1;i<=n;i++){
if(i>k)cnt-=f[i-k];
if( !((a[i]+cnt)&1) ){
f[i]=1;
cnt++;
ans++;
if(i>n-k+1)return -1;
}
}
return ans;
}
int main(){
cin>>n;
char c[2];
for(int i=1;i<=n;i++){
scanf("%s",c);
if(c[0]=='F')a[i]=1;
else a[i]=0;
}
int K,M=5000;
for(int k=1;k<=n;k++){
int tmp=calc(k);
if(tmp!=-1){
if(tmp<M){
M=tmp;
K=k;
}
}
}
cout<<K<<" "<<M<<endl;
return 0;
}
解决一个有趣的问题:如何通过最少的操作使所有牛朝同一方向,同时寻找最优的操作长度k。采用枚举法确定最佳策略。
466

被折叠的 条评论
为什么被折叠?



