【动态规划】Move ahead, 初级, LIS 程序完成

来源:互联网 发布:组成数据的基本单位是 编辑:程序博客网 时间:2024/05/16 19:11

原题网址:题目网址Topcoder


作为初步理解动态规划的自己照葫芦画瓢实现的小程序,还是比较有体会的,上次只是对问题进行了分析,对算法进行了设计。

实际上,对于算法的分析是有一点错误的。这里再次分析一下:

对于数据{1 17 5 10 13 15 10 5 16 8}

d[1] = 1,f[1] = +;

d[2] = {  v[1]-v[2]<0   },f[2] = -;

d[3] = {  v[1]-v[3]<0,因为是第一个与其相减,没有正负特性,所以可以采纳;

v[2]-v[3]>0, 正数,记录的f[2]是负数,相反,所以采纳 ;

max{d[1]+1,  d[2]+1},   所以采纳d[2]+1 }  f[3] = +;

d[4] = { v[1] - v[4] < 0 ,采纳;

v[2] - v[4] > 0 ,正数,记录f[2]负数,相反,采纳;

v[3] - v[4] <0 , 负数,记录f[3]的正数,相反,采纳;

max{ d[1]+1 , d[2]+1, d[3]+1 }  所以采纳d[3]+1}  f[4]= -;

d[5] = { v[1] - v[5] < 0 采纳;

v[2] - v[5] > 0 , 相反,采纳;

v[3] - v[5] <0 , 相反,采纳;

v[4] - v[5] <0 ,负数,记录f[4]负数,相同,不采纳;

max{ d[1]+1 , d[2]+1, d[3]+1 }  所以采纳d[3]+1;

这里和d[4]是一样的了,}  f[5] = - ;

…………

其中,d[i]表示前i个数中最大子序列;

v[i]表述输入字符串第i个字符;

f[i]表示前i个最大子序列中最后两个数字的差的正负性。


由此可以得出最终的实现代码:

/*61 7 4 9 2 5101 17 5 10 13 15 10 5 16 8*/#include <stdio.h>#define M 500int max(int x,int y){return x>y ? x:y;}//judge the two number's p&nint iscontrast(int a,int b){if( a > 0 && b < 0 || a<0 && b>0){return 1;}return 0;}int main(){int d[M];int v[M];int f[M];//1 for positive ,-1 for negtiveint i;int n;scanf("%d",&n);for(i=0 ; i<n ; i++){scanf("%d",&v[i]);}for(i=0 ; i< n; i++){d[i] =  0;}int j;d[0]=1;for(i=1 ; i < n ; i++){for(j=0 ; j< i ; j++){//if the condition is okif( j==0 || iscontrast(f[j],v[j]-v[i])==1 ){d[i] = max(d[i],d[j]+1);//set the p&n of the current position f[i] = v[j]-v[i] > 0 ? 1:-1;}}}printf("%d",d[n-1]);getchar();getchar();return 0;}


动归问题的核心就是建立起当前状态与前一个状态的状态转移方程,并根据具体情况存储必要的条件。

本题中关键的条件就是f[i] 前i个数字中最后两个数字差的正负性的存储以及设定。

同时动归的两重循环里面,各自的起始终止下标i,j  以及  初始化状态也需要比较好的确定

以上就是初级动归问题实现之后的感觉。

希望之后又更深入的了解吧。




0 0
原创粉丝点击