|
沙发
楼主 |
发表于 2015-10-31 20:46:21
|
只看该作者
我上课时候讲的是标准做法,虽然略有一点繁琐,但是清晰,扩展性强,同学们要认真去理解。虽然有的书上或者网上讲的比我的简单,但是,损失了一点扩展性,等熟练之后大家也可以学习网上的做法。
思路:用a数组表示每个数字的值,l数字表示目前最大的长度,f数组表示这个数字的前驱,p数组表示路径。
- #include<iostream>
- #include<iomanip>
- using namespace std;
- int a[11]= {0,1,7,3,5,9,2,8,6,4,99}; //假设有9个数字分别是1,7,3,5,9,2,8,6,4,第一个位子空着,最后一个是假标记
- int l[11]; //到当前为止的最长不下降序列的长度
- int f[11]; //当前最优决策时的前驱的编号
- int p[11];//输出路径时用的数组
- int i,j;
- int main()
- {
- for (i=0; i<=10; i++)
- {
- l[i]=1; //至少的长度是1
- f[i]=-1; //不需要前驱
- }
- for(i=2; i<=10; i++) ///枚举当前位置
- for (j=1; j<i; j++) ///枚举当前位置前面的所有可能
- if (a[j]<=a[i]) ///不下降
- if (l[j]+1>=l[i]) ///最长
- {
- l[i]=l[j]+1; ///决策
- f[i]=j; ///记录前驱
- }
- for (i=0; i<=10; i++)
- cout<<setw(4)<<a[i];
- cout<<endl;
- for (i=0; i<=10; i++)
- cout<<setw(4)<<l[i];
- cout<<endl;
- for (i=0; i<=10; i++)
- cout<<setw(4)<<f[i];
- cout<<endl;
- i=0;
- p[i]=10; ///最后一个绝对是最长的
- while (f[p[i]]!=-1) ///还有前驱
- {
- i++;
- p[i]=f[p[i-1]];
- }
- for (j=i; j!=-1; j--) cout<<a[p[j]]<<' '; ///输出最后的路径
- return 0;
- }
复制代码
|
|