codeforces Good bye 2016 E 线段树维护dp区间合并

题目大意:给你一个字符串,范围为‘0’~'9',定义一个ugly的串,即串中的子串不能有2016,但是一定要有2017,问,最少删除多少个字符,使得串中符合ugly串?

思路:定义dp(i, j),其中i=5,j=5,因为只需要删除2016当中其中一个即可,所以一共所需要删除的字符和需要的字符为20176,因此i和j只要5就够了。

然后转移就是dp(i,i) = 0, 如果说区间大小为1的话,那么如果是2017中的一个,那么就是dp(pos, pos+1) = 0, dp(pos,pos) = 1。但是如果pos为'6'这个字符,那么定义6这个pos=x转移就要为dp[x-1][x-1] = dp[x][x] = 1.然后我们再去转移就好了。

然后最后一定要注意线段树的合并顺序哦

//看看会不会爆int!数组会不会少了一维!
//取物问题一定要小心先手胜利的条件
#include <bits/stdc++.h>
using namespace std;
#pragma comment(linker,"/STACK:102400000,102400000")
#define LL long long
#define ALL(a) a.begin(), a.end()
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define haha printf("haha\n")
/*
定义dp(x,i,j)表示区间[0,x)内能够获得的2017的前缀长度为i的,至少要删除多少个字符
最少要删除多少个才能构成前缀为j的2017,然后我们不需要去管x,只需要用线段树去维护i,j即可。
*/
const int inf = 0x3f3f3f3f;
const int maxn = + ;
struct Node{
int dp[][];
}tree[maxn << ];
int n, q;
char ch[maxn];
map<char, int> id; inline void init(Node &t){
for (int i = ; i < ; i++)
for (int j = ; j < ; j++)
t.dp[i][j] = inf;
} Node Merge(Node a, Node b){
Node tmp; init(tmp);
for (int i = ; i <= ; i++)
for (int j = i; j <= ; j++)
for (int k = i; k <= j; k++)
tmp.dp[i][j] = min(tmp.dp[i][j], a.dp[i][k] + b.dp[k][j]);
return tmp;
} void display(Node t){
for (int i = ; i < ; i++){
for (int j = ; j < ; j++)
printf("%d ", t.dp[i][j]);
cout << endl;
}
} void buildtree(int l, int r, int o){
if (l == r){
init(tree[o]);
for (int i = ; i < ; i++)
tree[o].dp[i][i] = ;
int pos = id[ch[l]];
if (pos <= ) tree[o].dp[pos][pos] = , tree[o].dp[pos][pos + ] = ;
if (pos == ) tree[o].dp[][] = tree[o].dp[][] = ;
return ;
}
int mid = (l + r) / ;
if (l <= mid) buildtree(l, mid, o << );
if (r > mid) buildtree(mid + , r, o << | );
tree[o] = Merge(tree[o << ], tree[o << | ]);
//display(tree[o]);
} Node ans;
void query(int ql, int qr, int l, int r, int o){
if (ql <= l && qr >= r) {
if (ql == l) ans = tree[o];
else ans = Merge(ans, tree[o]);
return ;
}
int mid = (l + r) / ;
if (ql <= mid) query(ql, qr, l, mid, o << );
if (qr > mid) query(ql, qr, mid + , r, o << | );
} int main(){
int cnt = ;
id[''] = , id[''] = , id[''] = , id[''] = , id[''] = ;
for (char i = ''; i <= ''; i++) if(id.count(i) == ) id[i] = ++cnt;
cin >> n >> q;
scanf("%s", ch + );
buildtree(, n, );
for (int i = ; i <= q; i++){
int ql, qr; scanf("%d%d", &ql, &qr);
init(ans);
query(ql, qr, , n, );
if (ans.dp[][] >= inf) puts("-1");
else printf("%d\n", ans.dp[][]);
}
return ;
}

关键:线段树合并

codeforces Good bye 2016 E 线段树维护dp区间合并的更多相关文章

  1. Codeforces GYM 100114 D. Selection 线段树维护DP

    D. Selection Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100114 Descriptio ...

  2. Codeforces Round #271 (Div. 2) E题 Pillars(线段树维护DP)

    题目地址:http://codeforces.com/contest/474/problem/E 第一次遇到这样的用线段树来维护DP的题目.ASC中也遇到过,当时也非常自然的想到了线段树维护DP,可是 ...

  3. [Codeforces]817F. MEX Queries 离散化+线段树维护

    [Codeforces]817F. MEX Queries You are given a set of integer numbers, initially it is empty. You sho ...

  4. Codeforces Round #343 (Div. 2) D. Babaei and Birthday Cake 线段树维护dp

    D. Babaei and Birthday Cake 题目连接: http://www.codeforces.com/contest/629/problem/D Description As you ...

  5. Codeforces 834D The Bakery 【线段树优化DP】*

    Codeforces 834D The Bakery LINK 题目大意是给你一个长度为n的序列分成k段,每一段的贡献是这一段中不同的数的个数,求最大贡献 是第一次做线段树维护DP值的题 感觉还可以, ...

  6. Codeforces750E. New Year and Old Subsequence (线段树维护DP)

    题意:长为2e5的数字串 每次询问一个区间 求删掉最少几个字符使得区间有2017子序列 没有2016子序列 不合法输出-1 题解:dp i,p(0-4)表示第i个数匹配到2017的p位置删掉的最少数 ...

  7. Codeforces 1383E - Strange Operation(线段树优化 DP or 单调栈+DP)

    Codeforces 题目传送门 & 洛谷题目传送门 Yet another 自己搞出来的难度 \(\ge 2800\) 的题 介绍一个奇奇怪怪的 \(n\log n\) 的做法.首先特判掉字 ...

  8. 2016shenyang-1002-HDU5893-List wants to travel-树链剖分+线段树维护不同区间段个数

    肯定先无脑树链剖分,然后线段树维护一段区间不同个数,再维护一个左右端点的费用. 线段树更新,pushDown,pushUp的时候要注意考虑链接位置的费用是否相同 还有就是树链剖分操作的时候,维护上一个 ...

  9. 【BZOJ2164】采矿 树链剖分+线段树维护DP

    [BZOJ2164]采矿 Description 浩浩荡荡的cg大军发现了一座矿产资源极其丰富的城市,他们打算在这座城市实施新的采矿战略.这个城市可以看成一棵有n个节点的有根树,我们把每个节点用1到n ...

随机推荐

  1. Ubuntu16.04下安装显卡驱动记录

    安装环境及硬件信息 Ubuntu16.04 LTS 内核版本:4.4.0 显卡:Nvidia GeForce GTX 1060 安装过程 一.首先要下载好显卡驱动程序,官方网址:http://www. ...

  2. struts2--上传总结(限制大小和类型 非法上传的跳转)

    网上有很多版本,鉴于实践出真知的态度 我自己探索了一番 struts版本:2.3.16 限制大小: struts2默认是2M 所以如果要扩大大小限制,应该先配一个全局struts2最大上限 <c ...

  3. input value="值栈的值"

    <input type="text" value="<s:property value="myp.begintime"/>" ...

  4. Web站点性能-微观手段

    文章:网站性能优化 百度百科:高性能Web站点 文章:构建高性能WEB站点之 吞吐率.吞吐量.TPS.性能测试

  5. spring框架(3)— spring集合类的注入

    1.Car.java package com.eniac.beans; public class Car { private String type; private String factory; ...

  6. Spark Shuffle之Sort Shuffle

    源文件放在github,随着理解的深入,不断更新,如有谬误之处,欢迎指正.原文链接https://github.com/jacksu/utils4s/blob/master/spark-knowled ...

  7. PAT 甲级 1019 General Palindromic Number

    https://pintia.cn/problem-sets/994805342720868352/problems/994805487143337984 A number that will be ...

  8. Win2019 + Oracle18c SQLPLUS 命令行出现乱码的解决

    1. Win2019 中文版 安装了 Oracle数据库, dbca 建库时选择的 的字符集是 ZHS16GBK 然后发现使用sqlplus 时有乱码的现象如图示: 2. csdn 上面有一个博客有解 ...

  9. 第96天:CSS3 背景详解

    一.背景大小 background: url("images/bg.jpg") no-repeat;控制背景的大小1.具体数值background-size: 500px 500p ...

  10. MySQL事务提交过程

    一.MySQL事务提交过程(一) MySQL作为一种关系型数据库,已被广泛应用到互联网中的诸多项目中.今天我们来讨论下事务的提交过程. 由于mysql插件式存储架构,导致开启binlog后,事务提交实 ...