题目大意:白书例题p150 N头牛拍成一排, 没有牛有头朝前和头朝后,一个机器可以一次反转连续的几头牛, 但需要固定个数K, 也就是每次都反转K头牛,求解反转的最少的次数M和对应的K。注意:反转的牛不能少于K,也就是说在开头和结尾也必须反转K头。
解题思路:递归思想,将问题分解为更小的问题。如果开头第一个牛头朝前,那么其最少的次数就是第二头牛到n-1头牛时最小的次数。如果第一头牛头朝后,那么必须反转。
小技巧:不需要真正的去反转,这样复杂度太高,我们只需记录反转次数,当为奇数时牛就反转了。实现方式看代码。
AC代码:
#include <iostream>
#include <cstdio>
using namespace std;
int A[5005];
int n;
int solve(int k)
{
int ans = 0;
int d = 0;
int md[5005] = {0};
int sum = 0;
for(int i=0; i+k<=n; i++)
{
if((A[i] + ans)%2)
{
md[i] = 1;
ans++; sum++;
}
if(i-k+1 >=0) ans -= md[i-k+1];
}
for(int i=n-k+1; i<n; i++)
{
if((A[i] + ans) %2) return -1;
if(i-k+1 >= 0) ans -= md[i-k+1];
}
return sum;
}
int main()
{
scanf("%d", &n);
char s[10];
for(int i=0; i<n; i++)
{
scanf("%s", s);
if(s[0] == 'B') A[i] = 1;
}
int K = 0, M = 1 << 31 -1;
for(int i=1; i<=n; i++)
{
int x = solve(i);
if(x == -1) continue;
if(x < M)
{
M = x;
K = i;
}
}
printf("%d %d\n", K, M);
return 0;
}