USETC 1501 Defence Linces(DP+线段树+离散化)
来源:互联网 发布:oracle数据库入门书籍 编辑:程序博客网 时间:2024/05/20 15:59
题目链接
题意: 允许扣去一个连续子串的情况下,求剩下串的最长连续增长子串。 长度<= 200000. 数据大小: 1e9。
第一次使用离散化。其核心是: 利用数据个数相对较少,将N个数据建立与整数1~N的映射。 方法是, 先排序 ,再二分查早序号。
而线段树可以用来维护区间最大值, 这里是最大“没有间隔的连续子串长度”。
离散化和线段树只是用来优化的,下面解释一下算法主题:DP
个人认为动态规划最重要的是状态表示和状态转移。
① dp[ max_len ][ 2 ] ; dp[ i ][ 0 ] 表示以第 i 个数结尾的不含间隔的最长增长子串长度,dp[ i ][ 1 ]表示以第 i 个数结尾的含间隔的最长增长子串长度。
② dp [ i ][ 0 ]相对容易计算, dp[ i ][ 0 ] = a[ i ] > a [ i-1 ] ? dp[ i-1 ][ 0 ] + 1 : 1.
而dp[ i ][ 1 ]来自两方面: 一是继承了dp[ i-1 ][ 1 ]的间隔(此时a[ i ] > a[ i-1 ]),二是 a[ i ]的前面就是间隔 ,此时需要知道以 a[ x ] (a[ x ]<a[ i ] && x < i)结尾的连续子串的最大长度。
有个问题困惑了很久,如果找不到间隔怎么办? dp[ i ][ 1 ]是否失去了意义? 阳神一句精辟的话提醒了我: 不影响结果。
代码:
#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>using namespace std;#define Lson (cur)<<1,L,mid#define Rson (cur)<<1|1,mid+1,Rconst int maxn=200050;int dp[maxn][2],a[maxn],LiSan[maxn];int N;int Tree[maxn<<2];int Find(int x){int Low=1,High=N,mid;while(Low<High){mid=(Low+High)>>1;if(LiSan[mid]>=x) High=mid;else Low=mid+1;}return Low;}void update(int cur){Tree[cur] = max (Tree[cur] , Tree[cur<<1]);Tree[cur] = max (Tree[cur] , Tree[(cur<<1)|1]);}void Insert(int cur,int L,int R,int l,int r,int x){if(l<=L && R<=r){ Tree[cur]=max(Tree[cur] , x); return ;}int mid=(L+R)>>1;if(l<=mid) Insert(Lson,l,r,x);if(r>mid) Insert(Rson,l,r,x);update(cur);}int Query(int cur,int L,int R,int l,int r){if(l<=L && R<=r){return Tree[cur];}int mid=(L+R)>>1;int ans=0;if(l<=mid) ans=max(ans,Query(Lson,l,r));if(r>mid) ans=max(ans,Query(Rson,l,r));return ans;}int main(){//freopen("D:/input.txt","r",stdin);//freopen("D:/output.txt","w",stdout);int T;scanf("%d",&T);while(T--){memset(Tree,0,sizeof(Tree));memset(dp,0,sizeof(dp));scanf("%d",&N);for(int i=1;i<=N;i++){scanf("%d",&a[i]); LiSan[i]=a[i];}sort(LiSan+1,LiSan+N+1); int ans=0;dp[1][0]=1; dp[1][1]=1;int p=Find(a[1]);Insert(1,1,N,p,p,1);ans=max(ans,dp[1][0]), ans=max(ans,dp[1][1]);for(int d=2;d<=N;d++){dp[d][0] = a[d]>a[d-1] ? dp[d-1][0]+1 : 1;p=Find(a[d]);Insert(1,1,N,p,p,dp[d][0]);if(a[d] > a[d-1]) dp[d][1]=dp[d-1][1]+1;int tmp=0;if(p>1) tmp=Query(1,1,N,1,p-1);dp[d][1] = max(dp[d][1] , tmp+1);ans=max(ans,dp[d][0]),ans=max(ans,dp[d][1]);}printf("%d\n",ans);}return 0;}
- USETC 1501 Defence Linces(DP+线段树+离散化)
- UESTC 1501 - Defense Lines 离散化+线段树优化DP
- HDU 3607 线段树+离散化+DP
- 【dp+离散化+线段树优化】Paint
- codeforces 271E 离散化+线段树,dp优化
- hdu 3450 离散化+dp+线段树优化
- HDOJ 题目2836 Traversal(线段树,离散化,DP)
- HDU 2836 Traversal(线段树+离散化+DP)
- 51Nod - 1781 dp + 线段树 + 离散化
- codeforces 777E dp+线段树+离散化
- HDU 3016 Man Down(线段树+离散化+dp)
- 线段树+离散化
- 离散化 + 线段树
- 线段树离散化
- 线段树离散化
- codevs3037 线段覆盖5 离散化DP
- POJ_2528 线段树+离散化
- HDU3577 离散化+线段树
- leetcode Decode Ways Divide and Conquer
- Ubuntu系统如何安装软件
- Hdu 3221 Brute-force Algorithm (矩阵 欧拉定理降幂)
- 用GDB调试程序
- Study-Hard-网际层协议ICMP-简析(不断更新)
- USETC 1501 Defence Linces(DP+线段树+离散化)
- Java反射机制的原理及在Android下的简单应用
- Hadoop Streaming shell 脚本命令汇总
- ubuntu下chrome书签栏图标显示不正常 解决
- Section 1: Overview of Firebug
- 详解C++代码反汇编后的堆栈寄存器EBP和ESP
- 在cmd中输入: ipconfig /? 试试,你就知道/?的用法了
- 行人检测(Pedestrian Detection)资源
- oracle 11g bug:修改普通用户密码挂住,所有客户端均连接不上,生产中断