Codeforces Good Bye 2016 E. New Year and Old Subsequence
Posted heyuhhh
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Good Bye 2016 E. New Year and Old Subsequence相关的知识,希望对你有一定的参考价值。
题意:
给出一个长度为\(n\)的串,现在有\(q\)个询问,每个询问是一个区间\([l,r]\),要回答在区间\([l,r]\)中,最少需要删多少个数,满足区间中包含\(2017\)的子序列而不包含\(2016\)的子序列。
思路:
- 先不考虑多个询问,那么这个问题区间\(dp\)可以解决,状态定义中要附加状态转移的代价。
- 比如当前数字为\(7\),那么显然从状态\(201\)转移过来需要\(0\)的花费;但如果不要\(7\),那么从状态\(201\)到状态\(201\)则需要\(1\)的花费。
- 同理,若数字为\(6\)时,若前面处于状态\(201\)或者\(2017\),显然此时的状态只能保持不能发生其它转移,但是保持也需要\(1\)的代价才行。
- 以上我们定义的是将\(0,1,2,3,4\)分别表示状态\(\empty,2,20,201,2017\),对于每个数的状态转移都有确定的代价,这好像叫有限状态自动机?
- 考虑多个询问,因为每个询问是多个区间的问题,所以我们可以想到用线段树来保存区间信息,也就是说直接把\(dp\)挂树上去就行了。(区间\(dp\)支持区间合并)
妙啊。
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int N = 200005;
int n, q;
char s[N];
struct node
int a[5][5];
node() memset(a, INF, sizeof(a));
node operator + (const node &other) const
node res;
for(int i = 0; i < 5; i++)
for(int j = 0; j < 5; j++)
for(int k = 0; k < 5; k++)
res.a[i][j] = min(res.a[i][j], a[i][k] + other.a[k][j]);
return res;
tr[N << 2];
void build(int o, int l, int r)
if(l == r)
tr[o] = node();
for(int i = 0; i < 5; i++) tr[o].a[i][i] = 0;
if(s[l] == '2') tr[o].a[0][1] = 0, tr[o].a[0][0] = 1;
if(s[l] == '0') tr[o].a[1][2] = 0, tr[o].a[1][1] = 1;
if(s[l] == '1') tr[o].a[2][3] = 0, tr[o].a[2][2] = 1;
if(s[l] == '7') tr[o].a[3][4] = 0, tr[o].a[3][3] = 1;
if(s[l] == '6') tr[o].a[3][3] = tr[o].a[4][4] = 1;
return;
int mid = (l + r) >> 1;
build(o << 1, l, mid); build(o << 1|1, mid + 1, r);
tr[o] = tr[o << 1] + tr[o << 1|1];
node query(int o, int l, int r, int L, int R)
if(L <= l && r <= R) return tr[o];
int mid = (l + r) >> 1;
if(R <= mid) return query(o << 1, l, mid, L, R);
if(L > mid) return query(o << 1|1, mid + 1, r, L, R);
return query(o << 1, l, mid, L, R) + query(o << 1|1, mid + 1, r, L, R);
int main()
ios::sync_with_stdio(false); cin.tie(0);
cin >> n >> q;
cin >> s + 1;
build(1, 1, n);
while(q--)
int l, r; cin >> l >> r;
node ans = query(1, 1, n, l, r);
cout << (ans.a[0][4] > n ? -1 : ans.a[0][4]) << '\n';
return 0;
以上是关于Codeforces Good Bye 2016 E. New Year and Old Subsequence的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Good Bye 2016 D 模拟搜索?
Codeforces Good Bye 2016 E. New Year and Old Subsequence