最长递增(递减)子序列的贪心解法
从开始接触到每到求最长递增子序列都是用的动态规划方法,要开两个数组。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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++的值就是求得最长递增子序列的结果。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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上的跳高的蜗牛。