[BZOJ2090/2089] [Poi2010]Monotonicity 2/Monotonicity 树状数组优化dp
这个dp乍看不科学,仔细一看更不科学,所以作为一个执着BOY,我决定要造数据卡死波兰人民,但是我造着造着就......证出来了.........
这个就是把 < > =分开讨论每次找到f[i] 即以i为结尾的最长长度,然后一顿转移,那么我们发现如果只是讨论 符号那么由于符号顺序影响 我们的得到的是一个有后效性的dp 就是说我们这个时候找到最优解可能会影响最优解的得到,那么这个dp的正确性是怎样的呢?
首先我们假设我们找到了一个不是全部从最优转移点转移来的最优序列那么:I.最后一个点一定是从最优转移点转移过来 II. 倒数第二个点,如果不是最优转移点的结果,那么他可以把最后一个点顶掉,并且把自己换成最优转移点 (由于我们一直没有改变最优解,所以我们重复I II 就得到了一个最后两位都是最优解的最优序列) III. 然后我们看中间的点,我们总可以得到一个其之后的点都是由最优转移点转移而来的,那么我们可以把他换成最优转移er,那么得到了一个比原来肿了一点的新序列(我们先留着后面的点),那么现在我们的一串点他们之间都有符号,且他们都满足符号,只是现在不满足那个 s数组的顺序,那么我们发现在这次被操作的那个点的左右一段区间的符号是一样的,那么我们只要在这一段区间内删除掉连续的一段大小为新增长度的序列就可以了,我们从中间一个一个的删,删掉就补到中间来这样连续操作就可以了, 如果 中间那个数两边存在 = 就可以随意删,如果两边符号相同即 < < 或 > > 那么中间的店一定可以删掉 如果是 a<b>c 或 a>b<c 那么删掉b再按照a c 大小删掉左右的某个符号就好了,如果是a c相等那么就任意留一个a或c,那么如果我们现在只能删一个怎么办?如果只剩一个的话那么这个东西就是这段区间里唯一的旮沓了,那么他左右两边的符号一定相等(小证明:我们由于采取两边向中间沦陷的策略所以我们剩的点一定是要删除的区间两个边缘点之一,那么我们考虑这个区间,他一定正好覆盖两个轮回中间的一个轮回,那么边缘之一一定和另一个边缘的左出头一样)
我们重复以上操作可以把这个最优解转化为全部由最优转移点转移而来的最优解,因此要是没有一个不是全部从最优转移点转移来的最优序列那么我们的dp一定是对的如果有那么我们一定有全部由最优转移点转移而来的最优解,因此我们的dp一定可以找到最优解
这个故事告诉我们考场证dp是一个正确的选择.......
#include <cstdio>
#include <cstring>
#include <iostream>
#define Inf 1000000
#define MAXN 500000
#define r register
using namespace std;
int L[Inf+],B[Inf+];
inline int read()
{
r int sum=;
r char ch=getchar();
while(ch<''||ch>'')ch=getchar();
while(ch>=''&&ch<='')
{
sum=(sum<<)+(sum<<)+ch-'';
ch=getchar();
}
return sum;
}
inline void read(int &x)
{
r char ch=getchar();
while(ch!='='&&ch!='<'&&ch!='>')ch=getchar();
x=ch;
}
inline void ins_L(int x,int key){
while(x<=Inf) L[x]=key>L[x]?key:L[x],x+=x&(-x);
}
inline void ins_B(int x,int key){
while(x<=Inf) B[x]=key>B[x]?key:B[x],x+=x&(-x);
}
inline int get_B(int x){
r int ans=;
while(x>) ans=B[x]>ans?B[x]:ans,x-=x&(-x);
return ans;
}
inline int get_L(int x){
r int ans=;
while(x>) ans=L[x]>ans?L[x]:ans,x-=x&(-x);
return ans;
}
int n,k,a[MAXN+],J[Inf+];
Init s[MAXN+];
inline void Init()
{
n=read(),k=read();
for(int i=;i<=n;i++)a[i]=read();
for(int i=;i<=k;i++)read(s[i]);
}
inline int Max(int x,int y)
{
return x>y?x:y;
}
inline void work()
{
r int Ans=;
for(int i=;i<=n;i++)
{
r int ans=;
ans=get_B(Inf-a[i]);
ans=Max(ans,get_L(a[i]-));
ans=J[a[i]]>ans?J[a[i]]:ans;
ans+=;
Ans=ans>Ans?ans:Ans;
r int pos=(ans-)%k+;
if(s[pos]=='<')ins_L(a[i],ans);
else if(s[pos]=='>')ins_B(Inf+-a[i],ans);
else J[a[i]]=J[a[i]]>ans?J[a[i]]:ans;
}
printf("%d",Ans);
}
int main()
{
Init();
work();
return ;
}
[BZOJ2090/2089] [Poi2010]Monotonicity 2/Monotonicity 树状数组优化dp的更多相关文章
- HDU 6240 Server(2017 CCPC哈尔滨站 K题,01分数规划 + 树状数组优化DP)
题目链接 2017 CCPC Harbin Problem K 题意 给定若干物品,每个物品可以覆盖一个区间.现在要覆盖区间$[1, t]$. 求选出来的物品的$\frac{∑a_{i}}{∑b_ ...
- Codeforces 946G Almost Increasing Array (树状数组优化DP)
题目链接 Educational Codeforces Round 39 Problem G 题意 给定一个序列,求把他变成Almost Increasing Array需要改变的最小元素个数. ...
- LUOGU P2344 奶牛抗议 (树状数组优化dp)
传送门 解题思路 树状数组优化dp,f[i]表示前i个奶牛的分组的个数,那么很容易得出$f[i]=\sum\limits_{1\leq j\leq i}f[j-1]*(sum[i]\ge sum[j- ...
- 【题解】Music Festival(树状数组优化dp)
[题解]Music Festival(树状数组优化dp) Gym - 101908F 题意:有\(n\)种节目,每种节目有起始时间和结束时间和权值.同一时刻只能看一个节目(边界不算),在所有种类都看过 ...
- 【题解】ARC101F Robots and Exits(DP转格路+树状数组优化DP)
[题解]ARC101F Robots and Exits(DP转格路+树状数组优化DP) 先删去所有只能进入一个洞的机器人,这对答案没有贡献 考虑一个机器人只能进入两个洞,且真正的限制条件是操作的前缀 ...
- Codeforces 909C Python Indentation:树状数组优化dp
题目链接:http://codeforces.com/contest/909/problem/C 题意: Python是没有大括号来标明语句块的,而是用严格的缩进来体现. 现在有一种简化版的Pytho ...
- BZOJ3594: [Scoi2014]方伯伯的玉米田【二维树状数组优化DP】
Description 方伯伯在自己的农田边散步,他突然发现田里的一排玉米非常的不美. 这排玉米一共有N株,它们的高度参差不齐. 方伯伯认为单调不下降序列很美,所以他决定先把一些玉米拔高,再把破坏美感 ...
- Codeforces 629D Babaei and Birthday Cake(树状数组优化dp)
题意: 线段树做法 分析: 因为每次都是在当前位置的前缀区间查询最大值,所以可以直接用树状数组优化.比线段树快了12ms~ 代码: #include<cstdio> #include< ...
- BZOJ 3594: [Scoi2014]方伯伯的玉米田 (二维树状数组优化DP)
分析 首先每次增加的区间一定是[i,n][i,n][i,n]的形式.因为如果选择[i,j](j<n)[i,j](j<n)[i,j](j<n)肯定不如把后面的全部一起加111更优. 那 ...
- 4.9 省选模拟赛 划分序列 二分 结论 树状数组优化dp
显然发现可以二分. 对于n<=100暴力dp f[i][j]表示前i个数分成j段对于当前的答案是否可行. 可以发现这个dp是可以被优化的 sum[i]-sum[j]<=mid sum[i] ...
随机推荐
- jquery easyui alert闪一下的问题
最近做项目使用了 jQuery EasyUI,版本是 1.4.3.x,在使用alert方法的时候如果alert后面执行页面跳转的话alert的消息只会闪一下,就跳到其他页面了 $.messager.a ...
- CacheManager源码分析
计算rdd的某个分区是从RDD的iterator()方法开始的,我们从这个方法进入 然后我们进入getOrCompute()方法中看看是如何进行读取数据或计算的 getOrElseUpdate()方方 ...
- Linux Shell 与Linux常用命令
Linux的人际交互分为图形界面方式和命令行方式. Linux本身只是一个操作系统内核,而由X Window图形用户接口为Linux提供图形用户界面功能.可以把X Window理解为一个运行在Linu ...
- (数据科学学习手札10)系统聚类实战(基于R)
上一篇我们较为系统地介绍了Python与R在系统聚类上的方法和不同,明白人都能看出来用R进行系统聚类比Python要方便不少,但是光介绍方法是没用的,要经过实战来强化学习的过程,本文就基于R对2016 ...
- hoj第三场G-manhattanp ositioning system
---恢复内容开始--- 一.题意 在二维坐标系内,给定若干个点和目标点距离该点的曼哈顿距离,求是否存在唯一解使得目标点坐标为整数. 二.题解 重新思考题目模型,考虑曼哈顿距离一定时,几何含义为,以给 ...
- JAVA大作业汇总1
JAVA大作业 代码 ``` package thegreatwork; import javafx.application.; import javafx.scene.control.; impor ...
- 高德API+Python解决租房问题(.NET版)
源码地址:https://github.com/liguobao/58HouseSearch 在线地址:58公寓高德搜房(全国版):http://codelover.link:8080/ 周末闲着无事 ...
- allegro导入网表过程中出现的错误信息
1. 找不到焊盘PAD,下面这句话的意思是器件封装找不到焊盘46.pad WARNING(SPMHNI-): Unable to load symbol ): Could not find padst ...
- linux的常用易忘命令
1.查看软件安装路径 [root@localhost ~]# which gcc /usr/bin/gcc 查询进程 ps -ef |grep redis 查看端口 netstat -lntp |g ...
- CentOS7安装Oracle 11gR2 图文详解
注:Oracle11gR2 X64安装 一.环境准备 安装包: 1.VMware-workstation-full-11.1.0-2496824.exe 2.CentOS-7-x86_64-DVD-1 ...