在01序列上操作,给出一个初始序列以及目标序列和若干个区间赋值操作,问选择其中若干个操作对初始序列进行赋值,能使的初始序列与目标序列的差异最小值。
发现没有办法找到可行的贪心策略,想到dp,设dp[i]为当前的区间覆盖到的最远的点为i所能与目标序列(1-i)匹配上的最多个数,发现一些情况无法转移,但发现我们按照左端点排序后枚举转移就十分方便了,注意区间右端点相等时不要直接赋值,以及一些转移时要考虑两个区间之间的0是可以直接加入贡献的,具体就见代码。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define rep(i, s, t) for(int i = (s), i##E = (t); i <= i##E; ++i) 5 #define dec(i, s, t) for(int i = (s), i##E = (t); i >= i##E; --i) 6 7 const int N = 2e5 + 10, inf = 0x3f3f3f3f; 8 9 int n, m, C1[N], C0[N], f[N]; 10 11 struct Order 12 { 13 int l, r; 14 bool operator < (const Order& rhs)const 15 { 16 return l == rhs.l? r < rhs.r : l < rhs.l; 17 } 18 }Q[N]; 19 20 namespace Segment_tree 21 { 22 #define lc h << 1 23 #define rc lc | 1 24 #define M ((L + R) >> 1) 25 const int T = N << 2; 26 int fax[T][2]; 27 28 void modify(int h, int L, int R, int u, int val, bool opt) 29 { 30 if(L == R) fax[h][opt] = val; 31 else{ 32 if(u <= M) modify(lc, L, M, u, val, opt); 33 else modify(rc, M + 1, R, u, val, opt); 34 35 fax[h][opt] = max(fax[lc][opt], fax[rc][opt]); 36 } 37 } 38 39 int query(int h, int L, int R, int u, int v, bool opt) 40 { 41 if(u <= L && R <= v) return fax[h][opt]; 42 else{ 43 int ret = -inf; 44 if(u <= M) ret = query(lc, L, M, u, v, opt); 45 if(v > M) ret = max(ret, query(rc, M + 1, R, u, v, opt)); 46 return ret; 47 } 48 } 49 } 50 using namespace Segment_tree; 51 52 int main() 53 { 54 freopen("hamming.in", "r", stdin); 55 freopen("hamming.out", "w", stdout); 56 57 scanf("%d", &n); 58 rep(i, 1, n){ 59 int x; scanf("%d", &x); 60 C1[i] = C1[i-1] + bool(x != 0); 61 C0[i] = i - C1[i]; 62 } 63 scanf("%d", &m); 64 rep(i, 1, m) scanf("%d%d", &Q[i].l, &Q[i].r); 65 sort(Q + 1, Q + m + 1); 66 67 memset(fax, -inf, sizeof fax); 68 69 f[0] = 0; 70 modify(1, 0, n, 0, 0, 0); 71 modify(1, 0, n, 0, 0, 1); 72 73 rep(i, 1, m){ 74 int l = Q[i].l, r = Q[i].r; 75 76 int tmp = query(1, 0, n, 0, l - 1, 0); 77 f[r] = max(f[r], tmp + C1[r] - C1[l-1] + C0[l-1]); 78 79 if(l != r){ 80 int tmp = query(1, 0, n, l, r - 1, 1); 81 f[r] = max(f[r], tmp + C1[r]); 82 } 83 84 modify(1, 0, n, r, f[r] - C0[r], 0); 85 modify(1, 0, n, r, f[r] - C1[r], 1); 86 } 87 88 int answer = 0; 89 rep(i, 1, n) answer = max(answer, f[i] + C0[n] - C0[i]); 90 printf("%d\n", n - answer); 91 return 0; 92 }
原文:http://www.cnblogs.com/pbvrvnq/p/7932057.html