您的位置:首页 > 其它

poj 1887 Testing the CATCHER

2013-04-11 21:36 302 查看
分类:dp-lis 难度1.5

 

题意:求最长递增子序列。

最长递增子序列LIS的三种解法:

1、转换为最长公共子序列LCS(先排序,找排序后和原序列的LCS)

2、DP解法(O(n^2)),f(i)是以L[i]为末元素最长递增子序列的长度,遍历前i-1个元素,找满足L[j]<L[i]的max(f(j)),f[i]=f[j]+1,最后遍历f[i]找最大值,即为LIS

#include<cstdio>
#include<cstring>

const int N = 10010;
int l
,n,f
;

int main()
{
int cnt = 1;
for(;scanf("%d",&l[0]) && l[0]>=0;cnt++)
{
int i,j;
for(i=1;;i++)
{
scanf("%d",l+i);
if(l[i]<0) break;
}
n=i;
for(i=0;i<n;i++) f[i]=1;
for(i=n-2;i>=0;i--)
for(j=n-1;j>i;j--)
if(l[j]<=l[i] && f[j]+1>f[i])
f[i]=f[j]+1;
int ans=0;
for(i=0;i<n;i++)
if(f[i]>ans) ans = f[i];
printf("Test #%d:\n  maximum possible interceptions: %d\n\n",cnt,ans);
}
}

176k 63ms

3、优化DP解法(二分查找 O(nlogn)),B[f(j)]=L[j],每次在B[f(j)]中二分查找当前L[i]插入位置p,即满足B[p-1]<L[i],B[p]>L[i]的p(l[i]>B[当前max],则B[当前max+1]=l[i]),将B[p]的值替换为L[i],可证p=f(i),替换B[p]=L[i],并记录最大p即为LIS

#include<cstdio>
#include<cstring>

const int N = 10010;
int l
,n,f
,B
;

int bsrch(int v,int l,int r)
{
if(v>B[r]) return r+1;
if(l>=r) return l;
int m=(l+r)/2;
if(v<B[m]) return bsrch(v,l,m);
return bsrch(v,m+1,r);
}

int main()
{
int cnt = 1;
for(;scanf("%d",&l[0]) && l[0]>=0;cnt++)
{
int i,j,p;
for(i=1;;i++)
{
scanf("%d",l+i);
if(l[i]<0) break;
}
n=i;
for(i=0;i<n;i++) {f[i]=1;B[i]=0;}
int ans=0;
for(i=n-1;i>=0;i--)
{
f[i]=bsrch(l[i],1,ans);
B[f[i]]=l[i];
if(f[i]>ans) ans=f[i];
}
printf("Test #%d:\n  maximum possible interceptions: %d\n\n",cnt,ans);
}
}


192k 0ms

 

参考:http://www.programfan.com/blog/article.asp?id=13086

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  acm dp LIS