最长递增(递减)子序列的贪心解法

从开始接触到每到求最长递增子序列都是用的动态规划方法,要开两个数组。

 

代码
#include<stdio.h>
int main()
{
int i,j,t,n,m;
int a[905],b[905];
scanf(
"%d",&t);
while(t--){
scanf(
"%d%d",&n,&m);
for(i=0;i<n;i++)
scanf(
"%d",&a[i]),b[i]=1;
for(i=1;i<n;i++){
for(j=0;j<i;j++){
if(a[j]<a[i] && b[j]+1>b[i])
b[i]
=b[j]+1;
}
}
//printf("%d\n",b[n-1]);
if(b[n-1]>=m)
puts(
"good");
else
puts(
"bad");
}
return 0;
}

 

直到昨天晚上,队员和我讨论,我发现它使用的贪心求最长递增子序列,空间和时间复杂度都比动态规划的方法小。

方法:j=0;i从0到n-1循环,每次到a[i]>a[j],就让a[j+1]=a[i],j+=1; 如果a[i]<=a[j],就在a[0]从a[i-1]找到第一个比a[i]小的数替换为a[i]。

       到循环结束,就j++的值就是求得最长递增子序列的结果。

代码
#include<stdio.h>
int main()
{
int i,j,k,t,n,m;
int a[905];
scanf(
"%d",&t);
while(t--){
scanf(
"%d%d",&n,&m);
for(i=0;i<n;i++)
scanf(
"%d",&a[i]);
j
=0;
for(i=1;i<n;i++){
if(a[i]>a[j])
a[
++j]=a[i];
else
for(k=0;k<i;k++)
if(a[k]>=a[i]){
a[k]
=a[i];
break;
}
}
if(++j>=m)
puts(
"good");
else
puts(
"bad");
}
return 0;
}

 

上面代码的对应题目是zzuli上的跳高的蜗牛

posted @ 2010-07-11 09:00  孟起  阅读(749)  评论(0编辑  收藏  举报