POJ 3276 Face The Right Way(一维反转问题)

来源:互联网 发布:香港买mac转运到大陆 编辑:程序博客网 时间:2024/06/10 18:55


http://poj.org/problem?id=3276


反转两次等于没有反转,反转的次序是无关的。假设所有的格子进行一系列反转操作以后都变成F,那么可以把这一系列操作等价为,按照格子从左到右,每个区间反转1次或者不反转。对于最左边的格子,可以确定到底是反转还是不反转,然后再考虑下一个格子。

#include<cstdio>#include<cstring>#include<cmath>#include<string>#include<iostream>#include<algorithm>#define INF 0x3f3f3f3f#define N 5005using namespace std;int sum, res, n, K, ans, min_ans, f[N], a[N];int calc(int k){    sum = 0;    res = 0;    for (int i = 0; i <= n-k; i++)//f[i]表示[i,i-k+1]是否要反转    {        if ((sum + a[i]) % 2 == 1)        {            f[i] = 1;            res++;        }        sum += f[i];        if (i-k+1 >= 0) sum -= f[i-k+1];//最前面几个格子,不需要减    }    for (int i = n-k+1; i < n; i++)//从第n-k+1个格子开始,就不能够反转了,但是还是要知道通过前面的反转现在它的状态    {        if ((sum + a[i]) % 2 == 1)//第n-k+1个格子还可以用之前遗留下算好的sum,之后就要不断把f[i-k+1]减掉        {            return INF;        }        if (i-k+1 >= 0) sum-= f[i-k+1];    }    return res;}int main(){    scanf("%d", &n);    char s[3];    for (int i = 0; i < n; i++)    {        scanf("%s", s);        if (s[0] == 'B') a[i] = 1;        else a[i] = 0;    }    min_ans = INF;    for (int i = 1; i <= n; i++)    {        memset(f, 0, sizeof(f));        ans = calc(i);        if (ans < min_ans)        {            min_ans = ans;            K = i;        }    }    printf("%d %d\n", K, min_ans);    return 0;}


0 0
原创粉丝点击