您的位置:首页 > 其它

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

2014-05-05 16:03 197 查看
原题网址:题目网址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个最大子序列中最后两个数字的差的正负性。

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

/*
6
1 7 4 9 2 5
10
1 17 5 10 13 15 10 5 16 8
*/

#include <stdio.h>
#define M 500
int max(int x,int y)
{
return x>y ? x:y;
}

//judge the two number's p&n
int 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 negtive
int 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 ok
if( 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 以及 初始化状态也需要比较好的确定。

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

希望之后又更深入的了解吧。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: