博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ 1264 动态规划 + 树状数组
阅读量:5118 次
发布时间:2019-06-13

本文共 1703 字,大约阅读时间需要 5 分钟。

   “很难想的一道题不过不难写”—— Po

     这道题窝的思考过程十分坎坷。

    首先想着纯DP,类似于NOIP Day2T2的方法搞。

    设f[i][j]为强制将A[i]B串中第j个相同字符匹配的LCSs[i][j]为考虑到A[i]B串中第j个相同字符匹配(且强制不允许选这个字符之后)的LCS

    从这个状态设计就可以看得出来它既麻烦又sb

   

    先解释一下为什么要强制不允许选该字符之后——否则会造成交叉:之前的超过了当前字符。

   

    这道题和NOIP2015 Day2T2有一个不同:前者是一个具有特殊性质的LCS问题,而后者需要有一个序列被完全匹配。

   

    所以本题用DP就会产生一系列的问题。比如上面所述的那个状态就有一个很严重的问题:s[1][1]应该是什么?如果B串中第一个A[i]同字符出现在较后面的位置,那么s[1][1]甚至无法转移——因为它依赖于后面的状态,比如A[2]B串中第一个同字符在A[1]之前,那么就无法转移了。

   

   但是由这个失败的DP我们也能得到一些启示:我们的DP顺序应是按照B串中字符的顺序。如此一来,我们的状态也可以得到简化:f[i]表示以i结尾的LCS长度。考虑LCS的基本特点:当且仅当a[i]=b[j]时,f[i]+1。那么,我们就只需记录A串中每个字符出现的5个位置,按照B串的顺序扫描。对于B[j],我们找到A串中对应的5个位置,然后f[pos]=max{f[k]| k<pos}+1。注意要按k倒序搞,不然会造成重复加。如何取得最大值呢?线段树用不着:对于A[1..m]的连续区间的最大值,直接用树状数组即可——考虑树状数组求和的原理:一层一层地往上爬,把沿途的长条的值累和。这里,我们只要把每段“长条”维护的值改为本区间内最大值即可。注意各种地方n*5别忘了。

// BZOJ 1264#include 
#include
using namespace std; #define rep(i,a,b) for (int i=a; i<=b; i++) #define read(x) scanf("%d", &x) #define fill(a,x) memset(a, x, sizeof(a)) #define dep(i,a,b) for (int i=a; i>=b; i--) const int N=20000+5, S=6; int a[N*5], b[N*5], n, C[N*5], cnt[N], pos[N][S], f[N*5], ans=0; int lowbit(int x) { return x&(-x); } int max(int a, int b) { return a<=b ? b : a; } int get_max(int x) { int ret=0; for( ; x; x-=x&-x) ret=max(ret, C[x]); return ret; } void update(int x, int w) { for( ; x<=n*5; x+=x&-x) C[x]=max(C[x], w); }int main(){ read(n); rep(i,1,5*n) cnt[i]=C[i]=f[i]=0; rep(i,1,5*n) read(a[i]), pos[a[i]][++cnt[a[i]]]=i; rep(i,1,5*n) read(b[i]); rep(i,1,5*n) dep(j,5,1) { int p=pos[b[i]][j]; f[p]=max(f[p], get_max(p-1)+1); update(p, f[p]); ans=max(ans, f[p]); } printf("%d\n", ans); return 0;}

转载于:https://www.cnblogs.com/yearwhk/p/5119880.html

你可能感兴趣的文章
yii 跳转页面
查看>>
洛谷 1449——后缀表达式(线性数据结构)
查看>>
Data truncation: Out of range value for column 'Quality' at row 1
查看>>
Dirichlet分布深入理解
查看>>
字符串处理
查看>>
HtmlUnitDriver 网页内容动态抓取
查看>>
ad logon hour
查看>>
获得进程可执行文件的路径: GetModuleFileNameEx, GetProcessImageFileName, QueryFullProcessImageName...
查看>>
证件照(1寸2寸)拍摄处理知识汇总
查看>>
罗马数字与阿拉伯数字转换
查看>>
Eclipse 反编译之 JadClipse
查看>>
Python入门-函数
查看>>
[HDU5727]Necklace(二分图最大匹配,枚举)
查看>>
距离公式汇总以及Python实现
查看>>
一道不知道哪里来的容斥题
查看>>
window添加右键菜单
查看>>
Window7上搭建symfony开发环境(PEAR)
查看>>
Linux内核态、用户态简介与IntelCPU特权级别--Ring0-3
查看>>
第23月第24天 git命令 .git-credentials git rm --cached git stash clear
查看>>
java SE :标准输入/输出
查看>>