动态规划典型问题模板
一、最长上升子序列(Longest increasing subsequence)
状态(最关键):f[N]为动规数组,f[i]表示从第一个字符开始,以a[i]为最后一个字符的序列的最长递增子序列的长度。
由状态引出状态转移方程,因为f[i]的设定,所以可以去比较最后一个字符从而更新f[i];
- f[0]=1;
- 对于f[i],从第一个字符开始遍历0-(i-1)字符,if(a[i]>a[j]) f[i]=max(f[i],f[j]+1),从而找到最大值。
- 初始化时可以设置f[i]=1,这样方便max比较。
- 另外,f[n-1]只是以最后一个字符为结尾的子序列的最大长度,所以要得出LIS还需要遍历f[]。
例题:POJ2533 Longest Ordered Subsequence
AC代码
#include<iostream> #include<algorithm> using namespace std; int main() { int f[1005]; int a[1005]; int n; cin >> n; for (int i = 0; i < n; i++)cin >> a[i]; f[0] = 1; for (int i = 1; i < n; i++) { f[i] = 1; for (int j = 0; j < i; j++) { if (a[j] < a[i])f[i] = max(f[i], f[j] + 1); } } int ans = 1; for (int i = 0; i < n; i++)ans = max(ans, f[i]); cout << ans << endl; return 0; }