动态规划求一个数列的最长不下降子序列java版


       用java实现的算法如下:

 public class Test {

public static void main(String[] args) {
// TODO 自动生成的方法存根


int []a={3,18,7,14,10,12,23,41,16,24};//预查找的数组序列
int []b={1,1,1,1,1,1,1,1,1,1};//用来记录点i到n的最长不下降子序列的长度

//就是把i从0开始到9的各个子序列的长度都存到b数组中,为后面输出最长的那个子序列做准备。
int []c={0,0,0,0,0,0,0,0,0,0};//用来存储i在最长的不下降子序列的后继数据编号

//就像链表里面的next一样,为输出完整的子序列的顺序做准备
int n=10,i,j,max,p;//n为数组的长度,i,j为遍历数组时候用的下标,max用来存储以当前i下标为起点的子序列中最长的那个的长度。p用来指示出现最大长度的那个下标位置,为后面的c数组服务的。
for(i=n-2;i>=0;i--){//开始遍历了,顺序是从后往前开始遍历,实际上是从倒数第二个数字开始查找。
 max=0;
 p=0;
 for(j=i+1;j

//下面的这一句为本算法的关键步骤。判断是否a[i]
    if((a[i]max)){
       max=b[j];//满足条件时,将最大的记录点保存起来
   p=j;存储j位置到p
  }

//这个for语句执行完毕后才开始执行下面的if语句。
 if(p!=0){//表示有出现满足的条件,则把比较好的记录存到b,c数组中
    b[i]=b[p]+1;//初始情况下b全部赋值为1,故最少都是+1的情况
    c[i]=p;//c数组存储出现最长子序列的后一个的位置
  }
}

//至此,以上的for语句执行完毕

//自己添加的语句,看看到底b,c数组中存储的数据
for(int sum:b)
System.out.print(sum+" ");
System.out.println();
for(int sum:c)
System.out.print(sum+" ");


max=0;
p=0;
for(i=0;i  if(b[i]>max){
     max=b[i];
     p=i;
  }
System.out.println();
System.out.println("maxlong="+max);
System.out.print("result is:");

//我用的算法书使用伪代码写的,以下为我自己改编的
while(true){
if(c[p]!=0){//表示那个最长子序列还有下一个
System.out.print(a[p]+" ");//从数组a中找到并输出
p=c[p];}//从c数组中找到下一个位置
else {//这种情况为已经输到倒数第二个了
System.out.print(a[p]+" ");//输出最后一个
break;//跳出,程序结束
}
}
}
}


最后输出的结果为:

6 3 5 3 4 3 2 1 2 1 
2 6 4 6 5 6 7 0 9 0 
maxlong=6
result is:3 7 10 12 23 41 

你可能感兴趣的:(算法)