题意:
给一个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#include #include 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 = 0){ sum-=f[i-K+1]; } } return res;}int main(){ while(scanf("%d",&n)!=EOF){ getchar(); for(int i=0;i = 0 && M>m){ M=m; K=k; } } printf("%d %d\n",K,M); } return 0;}