poj---3276Face The Right Way
Posted sumaywlx
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj---3276Face The Right Way相关的知识,希望对你有一定的参考价值。
题意:
给一个01串,一次操作可以翻转连续的K的值,求最小的操作次数m及其对应的k值
tips:
1.考虑第i头牛来分析,它的状态跟谁和什么操作有关。
2.分析题目性质,找到问题求解的步骤,在求解中减小问题的规模。----题目问题肯定有解决流程。
3.递推的思想
4.看网上的题解还是鞥启发思路的,书和blog各有其好,结合食用效果最佳。
5.白书上的递推公式有点坑啊。。
6.代码中sum保存当前位置的前k-1格的操作数
//先要对问题进行分析,找出求解问题的思路 //将问题的规模逐渐缩小,横推过去 //区间的影响范围和 递推公式的理解 //只记录操作的次数,跟线段树的懒标记有点像 //卡在输入了..然而并不是,是中间有个循环i的赋值错了 //网上的题解对输入的处理是定义了一个字符数组,%s输入,最后只用判断第一位 //用getchar(),把回车字符过滤了也可以 //sum的解释https://blog.csdn.net/thudaliangrx/article/details/50444975 #include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int MAXN=5001; int dir[MAXN]; int f[MAXN]; int n; int clc(int K){ memset(f,0,sizeof(f)); int res=0; int sum=0; for(int i=0;i+K<=n;i++){ if(( dir[i]+ sum ) %2 != 0){ res++; f[i]=1; } sum+=f[i]; if(i-K+1 >= 0) { sum-=f[i-K+1]; } } //数组下标是从0开始的,所以第n个元素对应的下标是n-1 for(int i=n-K+1;i<n;i++){//(N-1)-0...(N-1)-(K-1)...(N-1)-K if( (dir[i]+sum)%2 != 0){ return -1; } if(i-K+1 >= 0){ sum-=f[i-K+1]; } } return res; } int main(){ while(scanf("%d",&n)!=EOF){ getchar(); for(int i=0;i<n;i++){ /*char x[5]; scanf("%s",&x); if(x[0] == ‘B‘){ dir[i]=1; } else{ dir[i]=0; } //getchar(); */ char x; scanf("%c",&x); if(x == ‘B‘){ dir[i]=1; } else{ dir[i]=0; } getchar(); } int K=1,M=n; for(int k=1;k<= n;k++){ int m=clc(k); if(m >= 0 && M>m){ M=m; K=k; } } printf("%d %d ",K,M); } return 0; }
以上是关于poj---3276Face The Right Way的主要内容,如果未能解决你的问题,请参考以下文章
POJ3276 Face The Right Way (尺取法)