反转 枚举

来源:互联网 发布:淘宝网手机版登录 编辑:程序博客网 时间:2024/06/07 05:02

反转一串字符串,使其一致,问翻转的最小长度和最小次数;枚举法,在求解时优化。

枚举k,用一个f[i]数组表示区间【i,i+k-1】是否进行反转,一个区间进行两次以上反转是多余的;最后看是否还有不一致的情况

#include<iostream>#include<algorithm>#include<string>#include<queue>#include<cmath>#include<vector>#include<stdlib.h>#include<iomanip>#include<list>#include<stack>#include<memory.h>#include<ctype.h>#include<set>#include<map>using namespace std;typedef long long ll;const int maxn = 5000 + 5;int n;int dir[maxn];int f[maxn];int cal(int k) {memset(f, 0, sizeof(f));int ans = 0;int sum = 0;for (int i = 0; i + k <= n; i++) {if ((dir[i] + sum) % 2 != 0) {ans++;f[i] = 1;}sum += f[i];if (i - k + 1 >= 0) {sum -= f[i - k + 1];}}for (int i = n - k + 1; i < n; i++) {if ((dir[i] + sum) % 2 != 0)return -1;if (i - k + 1 >= 0) {sum -= f[i - k + 1];}}return ans;}void solve() {int k = 1, M = n;for (int kk=1; kk <= n; kk++) {int m = cal(kk);if (m >= 0 && M > m) {M = m;k = kk;}}printf("%d %d\n", k, M);}int main() {scanf("%d", &n);char ch;for (int i = 0; i < n; i++) {cin >> ch;if (ch == 'F')dir[i] = 0;else dir[i] = 1;}solve();}