题意:给一组字符只有F或者B,代表向前或向后,每次可以反转k个连续的数。问最少的反转次数和能取得最小次数的最小的k
暴力肯定不行,必须要用一种减小复杂度的操作。没有想出来怎么做,看了别人的博客
本来写对了的,但是输出答案的时候k和次数输出反了,看了半天才发现
#pragma warning(disable:4996)
#include<iostream>
#include<cstring>
#include<cstdio>
#include<climits>
#include<algorithm>
#include<vector>
#include<cmath>
#include<queue>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
const int MAXN = 10005;
int a[MAXN],temp[MAXN];
int main()
{
//ansk,ansn代表答案
int n, ansk, ansn, i, j, k, cnt;
char s[2], ls;
while (scanf("%d", &n) == 1)
{
//把第0个字符设置为'F'
ls = 'F';cnt = 0;
for (i = 1;i <= n;i++)
{
//和上一个比较,相同为0不同为1
scanf("%s", s);
if (s[0] == ls)a[i] = 0;
else a[i] = 1;
ls = s[0];
}
ansk = 1;ansn = n;
for (k = 1;k <= n;k++)
{
//复制原来的数组
for (i = 1;i <= n;i++)
temp[i] = a[i];
cnt = 0;
for (i = 1;i <= n-k+1;i++)
{
//如果不同,就反转k个数
//但是反转后对于这k个数来说,前后之间的关系没有变
//所以只改变第k+i个数
if (temp[i])
{
cnt++;temp[i+k] ^= 1;
}
}
for (i = n - k + 2;i <= n;i++)
{
//如果后面的数还有1,说明k不能取这个值
if (temp[i] == 1)
{
cnt = -1;break;
}
}
if (cnt != -1)
{
//更新答案
if (ansn > cnt)
{
ansn = cnt;
ansk = k;
}
}
}
printf("%d %d\n", ansk, ansn);
}
return 0;
}