标签:动态规划
问题描述:求一个数组的最长递减子序列 比如{9,4,3,2,5,4,3,2}的最长递减子序列为{9,5,4,3,2}。
思路:这是一个标准的动态规划的问题,在不理解算法的时候,最感觉可以使用递归的思想,其实也是正确的,在最后给出一个递归的方法,在知道是动态规划问题以后,就需要进行分析,我们需要一个辅助数组记录信息,假如源数组为src,辅助数组为table,table[i]数组中记录着到src[0]~src[i]这个子数组中包含src[i]构成的最长单调子序列的长度(一定要注意就是table[i]记录了包含src[i]构成的递减序列中最长的那个,也就是以src[i]为结尾的最长递减子序列),如果src[i]大于以前的所有元素,那么table[i]=1.
最后的结果就是,table[i] =max{table[k]+1, src[i] > src[k] && 0<k<i},这是初始化了table数组,那么最长递减子序列为max{table[i],0<i<n}.
但是需要打印最长子序列,我们已经记录了max{table[i],0<i<n}的下标,那么我们就知道了最长子序列的最后一个元素,同时知道了最长子序列的长度。下面就是递归调用,假如我们已经知道table[k]最大,那么src[k]就是最长递减子序列中的最后一个,如果table[i]+1 = table[k] && src[i] < table[k]时,那么就需要答应src[i]。
#include <stdio.h>
#include <stdlib.h>
void Find(int src[],int n,int table[])
{
table[0]= 1;
int i,j,maxi = 0;
for(i=0;i<n;i++)
{
table[i]=1;
for(j=0;j<i;j++)
{
/* 这里可能是常有的错误
if( src[j] > src[i])
{
table[i] = table[j] +1;
if(src[j]>src[i])
table[i] = table[j]+1;
if(table[i] > table[maxi])
maxi = i;
}
*/
if(src[j]> src[i] && table[j]+1 > table[i])
{
table[i] = table[j]+1;
//这个的作用是为了打印存在的,maxi记录最长子序列中最后一个数组元素
if(table[i] > table[maxi])
maxi = i;
}
}
}
// printf("%d\r\n",maxi);
}
void print(int src[],int table[],int maxi)
{
int i=maxi-1;
for(;i>=0;i--)
{
if(table[maxi] == table[i]+1 && src[i] > src[maxi])
{
print(src,table,i);
break;
}
}
printf("%d ",src[maxi]);
}
void FindLongestDSCArray2(int *arr, int n){
int mark[9];
int link[9];
int i = 0;
for(i=0;i<n;i++){
mark[i] = 0;
link[i] = -1;
}
//link[0] = 1;
int j = 0, maxMark = 0;
for(i=0;i<n;i++){
maxMark = 0;
for(j=0;j<i;j++){
if(arr[j]>arr[i]){
if(maxMark<mark[j]){
maxMark = mark[j];
link[i] = j;
}
}
}
mark[i] = maxMark+1;
}
for(i=0;i<9;i++)
printf("%d ",mark[i]);
printf("\r\n");
for(i=0;i<9;i++)
printf("%d ",link[i]);
printf("\r\n");
/*
//Print()
int node = 0;
maxMark = 0;
for(i=0;i<n;i++){
if(mark[i]>maxMark)
node = i;
}
while(node != -1){
printf("%d ",arr[node]);
node = link[node];
}
*/
}
int main()
{
int src[]={9,4,3,2,5,4,3,2,4};
int table[9];
Find(src,9,table);
FindLongestDSCArray2(src,9);
int i=0;
for(;i<9;i++)
printf("%d ",table[i]);
printf("\r\n");
return 0;
}
标签:动态规划
原文地址:http://blog.csdn.net/yusiguyuan/article/details/39337369