这个题算式我折腾了好几天弄懂的第一个题吧!
这本书上说动态规划是记录中间过程为了节省计算时间,那本书上说动态规划就是建立在地推的基础上,唉 ,就是不会求。。。。
最长升序子序列
http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=1299
最长上升子序列
Time Limit: 3000ms Memory limit: 65536K 有疑问?点这里^_^
题目描述
一个数的序列bi,当b
1 < b
2 < ... < b
S的时候,我们称这个序列是上升的。对于给定的一个序列(a
1, a
2, ..., a
N),我们可以得到一些上升的子序列(a
i1, a
i2, ..., a
iK),这里1<= i
1 < i
2 < ... < i
K <= N。比如,对于序列(1, 7, 3, 5, 9, 4, 8),有它的一些上升子序列,如(1, 7), (3, 4, 8)等等。这些子序列中最长的长度是4,比如子序列(1, 3, 5, 8)。
你的任务,就是对于给定的序列,求出最长上升子序列的长度。
你的任务,就是对于给定的序列,求出最长上升子序列的长度。
输入
输入的第一行是序列的长度N (1 <= N <= 1000)。第二行给出序列中的N个整数,这些整数的取值范围都在0到10000。
输出
最长上升子序列的长度。
示例输入
7 1 7 3 5 9 4 8
示例输出
4
还是从1阶段2状态3决策来说吧 这题应该拿到后知道有几个数就是几个状态。
最开始我是那到一个动态规划的题先想他的递归公式怎么去递归的解决,然后想那个实现递归的树 ,数有几层我就认为是有几个阶段 ,也不知道这样想对不对。树上所有的节点就是各种状态, 决策嘛就是从这个节点到下一层节点要干的事。
因为我只是在学动态规划 所以本题提供的答案是O(n²)阶的 至于本题的O(logn*n)阶的在这不提
#include<iostream>
using namespace std;
int ans[1001];
int main()
{
int n;
cin>>n;
int arr[1001];
for(int i=0;i<n;i++)
{
cin>>arr[i];
}
ans[0]=1;
for(int i=1;i<n;i++)
{
int m=0;
for(int j=0;j<i;j++)
{
if(arr[j]<arr[i]&&ans[j]>m)
{
m=ans[j];
}
}
ans[i]=m+1;
}
cout<<ans[n-1]<<endl;
cin>>n;
return 0;
}
代码的关键是中间的两层for循环 i代表当前位置是第几个,j就是从i的前面找出一个比arr[i]小并且ans大的(ans[i]是记录了从开始到i时的最长的个数找出1--i-1 个数的最长值之后ans[i]=m+1;就是前i个的最长长度了。
好了 。。时间不早了 回去睡觉吧。
感谢自己坚持!