SRM 589

来源:互联网 发布:淘宝助理图片校验出错 编辑:程序博客网 时间:2024/05/03 09:03

分M大于17的情况和M小于17两种


M大于17: 成段变化的一共只有N/M<17种,所以2^(N/M)枚举哪几段变化了,单个变化的贪心做


M小于等于17:dp[i][1<<17]来做,只要保存当前位置前的M个的值就够了


#include <vector>#include <list>#include <map>#include <set>#include <deque>#include <stack>#include <bitset>#include <algorithm>#include <functional>#include <numeric>#include <utility>#include <sstream>#include <iostream>#include <iomanip>#include <cstdio>#include <cmath>#include <cstdlib>#include <ctime>#include <cstring>using namespace std;class FlippingBitsDiv1 {public:int getmin(vector<string> , int);};int inf = 1000000000;string s;int a[305];int solveBigM(int m) {int n = s.size();int k = n / m;int ans, p;int i, j, r;ans = inf;for (i = 0; i < (1 << k); ++i) {int change = 0;p = 0;for (j = 0; j < n; ++j)a[j] = s[j] - '0';for (j = n - 1; j >= 0; --j) {if ((j + 1) % m == 0) {if (i & (1 << (j / m))) {p++;change ^= 1;}}a[j] ^= change;}for (j = 0; j < m; ++j) {int x[2];x[0] = x[1] = 0;for (r = j; r < n; r += m) {x[a[r]]++;}p += min(x[0], x[1]);}ans = min(p, ans);}return ans;}void put(int j) {int i;for (i = 7; i >= 0; --i) {if (j & (1 << i))putchar('1');elseputchar('0');}}int dp[2][1 << 17];int solveSmallM(int m) {int n = s.size();int pre, now;int i, j, k;for (j = 0; j < (1 << m); ++j) {dp[0][j] = 0;dp[1][j] = inf;}for (now = 1, pre = 0, i = 0; i < n; ++i, now = 1 - now, pre = 1 - pre) {for (j = 0; j < (1 << m); ++j) {if (dp[pre][j] == inf)continue;int jj;if (a[i] == (j >> (m - 1))) {jj = ((j * 2 + a[i]) & ((1 << m) - 1));dp[now][jj] = min(dp[now][jj], dp[pre][j]);if (i % m == 0) {jj = (((j ^ ((1 << m) - 1)) * 2 + (a[i] ^ 1)) & ((1 << m)- 1));dp[now][jj] = min(dp[now][jj], dp[pre][j] + 2);}} else {jj = ((j * 2 + (a[i] ^ 1)) & ((1 << m) - 1));dp[now][jj] = min(dp[now][jj], dp[pre][j] + 1);if (i % m == 0) {jj = (((j ^ ((1 << m) - 1)) * 2 + a[i]) & ((1 << m) - 1));dp[now][jj] = min(dp[now][jj], dp[pre][j] + 1);}}dp[pre][j] = inf;}}int ans = inf;for (j = 0; j < (1 << m); ++j) {ans = min(ans, dp[pre][j]);}return ans;}int FlippingBitsDiv1::getmin(vector<string> S, int M) {int i;s.clear();for (i = 0; i < S.size(); ++i)s = s + S[i];for (i = 0; i < s.size(); ++i)a[i] = s[i] - '0';if (M > 17)return solveBigM(M);elsereturn solveSmallM(M);}


0 0
原创粉丝点击