您的位置:首页 > 产品设计 > UI/UE

hdu 1423 Greatest Common Increasing Subsequence

2012-10-14 22:40 429 查看
Greatest Common Increasing Subsequence

hdu 1423 GCIS (n^2)

省赛的时候,这个题目看了良久,都没想到O(n^2)的算法。后来苏犇看到GCIS的时候就让看模版,然后在吉大的模版上看到了这个

然后我们就顺利的1Y.我又看了一下这个题目,找了好多博客(不是挂了,就是讲的很不清楚)。。然后看到了http://www.tyvj.cn/bbs/Discuss_Show.aspx?id=30583这个博客,博主讲的很给力。

这个题目的状态与LCS的状态差不多,只不过加了些约束dp[i][j]表示a串走到第i个数字,b串走到第j个数字,然后以b串的第j个数字为最终的最长公共递增子序列的长度这样我们就可以直接搞出方程了:

dp[i][j] = dp[i - 1][j] if(a[i] != b[j])

dp[i][j] = max(dp[i - 1][k]) + 1 , 1 <= k < j && b[k] < a[i]

由方程其实我们很容易想到用滚动数组优化,在实现的时候由于在相等的时候b串第j个数字是固定的,所以我们可以很容易的在扫的时候直接计算出对应最大值。。

/*
author    : csuchenan
prog      : hdu 1423
algorithm : Greatest Common Increase Subsequence O(n^2)
dp[i][j] 以b串的j为终点的最长公共上升子序列的长度。
dp[i][j] = dp[i - 1][j] if(a[i] != b[j])
dp[i][j] = max(dp[i - 1][k]) + 1 , 1 <= k < j && b[k] < a[i]
由于递推的时候只涉及到i-1,所以我们可以直接用滚动数组优化
详见程序
*/

#include <cstdio>
#include <cstring>
const int maxn = 550 ;

int dp[maxn] ;
int a[maxn]  ;
int b[maxn]  ;

int GCIS(int la , int lb){
memset(dp , 0 , sizeof(dp)) ;
int i , j , mx ;
for(i = 1 ; i <= la ; i ++){
for(mx = 0 , j = 1 ; j <= lb ; j ++){
if(b[j] < a[i] && mx < dp[j]){
mx = dp[j] ;
}
if(b[j] == a[i]){
dp[j] = mx + 1 ;
}
}
}
for(i = 1 , mx = 0 ; i <= la ; i ++){
mx = mx > dp[i] ? mx : dp[i] ;
}
return mx ;
}

int main(){
int la , lb ;
int Tcas ;
scanf("%d" , &Tcas) ;
while(Tcas--){
scanf("%d" , &la) ;
for(int i = 1 ; i <= la ; i ++){
scanf("%d" , &a[i]) ;
}

scanf("%d" , &lb) ;
for(int i = 1 ; i <= lb ; i ++){
scanf("%d" , &b[i]) ;
}

printf("%d\n" , GCIS(la , lb)) ;
if(Tcas)
puts("") ;
}
return 0 ;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: