SWUN CD8

来源:互联网 发布:2017阿里大数据平台 编辑:程序博客网 时间:2024/05/12 01:09

题目地址: http://218.194.91.48/acmhome/problemdetail.do?&method=showdetail&id=1075

 

方法: 哈希 +  两个DP

 

应某人要求,写了题解~~

 

(特地写了个 "深奥" 的Code~~~,看懂不看懂,就不是我事儿了~)

 

先对变量进行解释:

                  n :表示有n个成员。

                  last :表示上一次输入的成员。

                  now :表示当前输入的成员。

                  rm : record_numbers ,用于哈希,rm[ i ] 表示以i成员为结尾的最大连续上升序列。

                  len : 第一个dp,表示以当前成员为结尾的,最大连续上升序列的长度。

                  flen : 第一个dp,表示以上一个成员为结尾的,最大连续上升序列的长度。

                  len2 : 第二个dp,表示以当前成员为结尾的,去除连续的一段序列之后,所能达到的最大连续上升序列。

                  flen2 : 第二个dp,表示以上一个成员为结尾的,去除连续的一段序列之后,所能达到的最大连续上升序列。

 

于是很好理解,如果 last<now ,那么 len = flen+1 ,否则 len =1。

 

然后比较之前得到的,以 now 结尾的最大连续上升序列的长度,如果现在这个上升序列长度更大,
则替换。

 

接下去,则是从 1 到 now-1 之间,找到一个以 [比now小的数] 为结尾的最大上升序列,接在now前面。那么这时,我们所忽略的连续序列为最优的忽略。

 

同时,len2 就是 [之前最大上升序列的长度mx] + 1

 

现在就是第二个dp的判断了,如果 len2<=flen2 ,同时 last<now,那么就表示:now可以放在last后面,并且flen2+1>len2 。于是len2 = flen2+1

 

这就表示了,删除了一段连续序列之后,以当前成员为结尾,最大上升序列为 len2 。

 

于是用 res 来更新以每一个成员结尾的最大连续上升序列长度。

 

 = = 、  其实解释的很详细了,看过之后,Code应该懂了吧。

 

#include<cstdio>int main(){int i,j,mx,n,res,now,last,len,flen,len2,flen2,rm[105]={0};scanf("%d",&n);for(res=0,last=flen=flen2=0,i=1;i<=n;last=now,flen=len,flen2=len2,i++){scanf("%d",&now);len=last<now?flen+1:1;rm[now]<len?rm[now]=len:0;for(mx=0,j=1;j<now;j++)mx<rm[j]?mx=rm[j]:0;len2=mx+1;flen2>=len2&&last<now?len2=flen2+1:0;res<len2?res=len2:0;}printf("%d\n",res);return 0;}

原创粉丝点击