ARC 085 NRE

  在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 - answer);
91     return 0;
92 }
原文地址:https://www.cnblogs.com/pbvrvnq/p/7932057.html