codeforces Good bye 2016 E 线段树维护dp区间合并
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区间合并的更多相关文章
- Codeforces GYM 100114 D. Selection 线段树维护DP
D. Selection Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100114 Descriptio ...
- Codeforces Round #271 (Div. 2) E题 Pillars(线段树维护DP)
题目地址:http://codeforces.com/contest/474/problem/E 第一次遇到这样的用线段树来维护DP的题目.ASC中也遇到过,当时也非常自然的想到了线段树维护DP,可是 ...
- [Codeforces]817F. MEX Queries 离散化+线段树维护
[Codeforces]817F. MEX Queries You are given a set of integer numbers, initially it is empty. You sho ...
- 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 ...
- Codeforces 834D The Bakery 【线段树优化DP】*
Codeforces 834D The Bakery LINK 题目大意是给你一个长度为n的序列分成k段,每一段的贡献是这一段中不同的数的个数,求最大贡献 是第一次做线段树维护DP值的题 感觉还可以, ...
- Codeforces750E. New Year and Old Subsequence (线段树维护DP)
题意:长为2e5的数字串 每次询问一个区间 求删掉最少几个字符使得区间有2017子序列 没有2016子序列 不合法输出-1 题解:dp i,p(0-4)表示第i个数匹配到2017的p位置删掉的最少数 ...
- Codeforces 1383E - Strange Operation(线段树优化 DP or 单调栈+DP)
Codeforces 题目传送门 & 洛谷题目传送门 Yet another 自己搞出来的难度 \(\ge 2800\) 的题 介绍一个奇奇怪怪的 \(n\log n\) 的做法.首先特判掉字 ...
- 2016shenyang-1002-HDU5893-List wants to travel-树链剖分+线段树维护不同区间段个数
肯定先无脑树链剖分,然后线段树维护一段区间不同个数,再维护一个左右端点的费用. 线段树更新,pushDown,pushUp的时候要注意考虑链接位置的费用是否相同 还有就是树链剖分操作的时候,维护上一个 ...
- 【BZOJ2164】采矿 树链剖分+线段树维护DP
[BZOJ2164]采矿 Description 浩浩荡荡的cg大军发现了一座矿产资源极其丰富的城市,他们打算在这座城市实施新的采矿战略.这个城市可以看成一棵有n个节点的有根树,我们把每个节点用1到n ...
随机推荐
- Python:模块学习——sys模块
sys模块常见函数和变量 sys.argv:命令行参数,实现从程序外部向程序传递参数 [注]:(1) sys.argv[0] 表示代码本身的文件路径 (2)sys.argv是一个元组,可以用[ ]提取 ...
- python 动态获取当前运行的类名和函数名的方法
一.使用内置方法和修饰器方法获取类名.函数名 python中获取函数名的情况分为内部.外部,从外部的情况好获取,使用指向函数的对象,然后用__name__属性 复制代码代码如下: def a():pa ...
- 博弈---ZOJ 3057 Beans Game(DP博弈)
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3057 有豆类三个桩.TT和DD挑选任意数量的豆子从任何两堆轮流任何桩或相同 ...
- 解决Ubuntu(Linux)平台下Sublime Text 3 安装中文输入支持库后 开启gnome-terminal报错的问题
在Ubuntu下安装Sublim Text3后发现无法输入中文,按照此链接的方法解决后.然后用下列代码配置C++的编译系统: { "cmd":["g++",&q ...
- DELL服务器PXE前期处理
thaks:https://www.cnblogs.com/520ZXL/ PXE批量推系统,服务器要具备条件:raid处理好,设置为pxe启动,与PXE服务器网络要通 先进入磁盘阵列(ctrl+R) ...
- CCF——门禁系统201412-1
问题描述 涛涛最近要负责图书馆的管理工作,需要记录下每天读者的到访情况.每位读者有一个编号,每条记录用读者的编号来表示.给出读者的来访记录,请问每一条记录中的读者是第几次出现. 输入格式 输入的第一行 ...
- js动态显示指定的时间
<p id="timeShow">17:0:50</p> <script> setInterval("time()", 10 ...
- asp.net core 登录身份认证(Cookie)
asp.net core 2最简单的登录功能 源代码在此 创建asp.net core Web Mvc项目 配置下选项 项目目录结构 在Models文件夹下新建两个实体类 public class T ...
- 【OpenGL】使用FreeType库加载字体并在GL中绘制文字
FreeType用起来比较麻烦,这里写了一份简单的示例代码,仅供参考. 实现了FT库生成字符位图,并上传到GL纹理. 实现了字符位图缓存功能,多个字符图像保存在同一个纹理中. 实现了简单的字体管理框架 ...
- Django安装及简介
一. Django简介 Python下有许多款不同的 Web 框架.Django是重量级选手中最有代表性的一位.许多成功的网站和APP都基于Django. Django是一个开放源代码的Web应用框架 ...