码迷,mamicode.com
首页 > 其他好文 > 详细

动态规划典型问题模板

时间:2019-06-30 09:56:32      阅读:137      评论:0      收藏:0      [点我收藏+]

标签:ons   返回值   长度   sequence   动态规划   i++   poj 2533   incr   pre   

动态规划典型问题模板

一、最长上升子序列(Longest increasing subsequence)

状态:以ak(k=1,2,3...N)为终点的最长递增子序列的长度。

状态转移方程:

  • MaxLen(1) = 1
  • MaxLen(k) = Max{ MaxLen(i): 1<i<k 且 ai<ak 且 k≠1 } +1

这个转移方程的意思就是,MaxLen(k)的值,就是在ak左边,“终点”数值小于ak,且长度最大的那个上升子序列的长度再加1。因为ak左边任何“终点”小于ak的子序列,加上ak后就能形成一个更长的子序列。

注意:读入数据和状态转移都以1为起点。

数据结构:

const int N = 10010;
int a[N];//记录原序列
int dp[N];//dp[i]表示包括第i位之前序列的最长上升子序列长度
int len;//原序列长度

LIS():动规求解序列各位的最长递增子序列长度

int LIS()
{
    int tmp = 1;//返回值,表示整个序列的LIS值
    for (int i = 1; i <= len; i++)
    {
        dp[i] = 1;//都初始化为1,方便后面直接比较
        for (int j = 1; j < i; j++)
        {
            if (a[j]<a[i] && dp[j] + 1>dp[i]) dp[i] = dp[j] + 1;
        }
        if (dp[i] > tmp) tmp = dp[i];
    }
    return tmp;
}

例:POJ 2533 Longest Ordered Subsequence

AC代码

#include<cstdio>
#include<cstring>

const int N = 1010;
int a[N];//记录原序列
int dp[N];//dp[i]表示包括第i位之前序列的最长上升子序列长度
int len;//原序列长度

int LIS()
{
    int tmp = 1;//返回值,表示整个序列的LIS值
    for (int i = 1; i <= len; i++)
    {
        dp[i] = 1;//都初始化为1,方便后面直接比较
        for (int j = 1; j < i; j++)
        {
            if (a[j]<a[i] && dp[j] + 1>dp[i]) dp[i] = dp[j] + 1;
        }
        if (dp[i] > tmp) tmp = dp[i];
    }
    return tmp;
}

int main()
{
    scanf("%d", &len);
    for (int i = 1; i <= len; i++)scanf("%d", &a[i]);
    int ans = LIS();
    printf("%d", ans);
    return 0;
}

 

动态规划典型问题模板

标签:ons   返回值   长度   sequence   动态规划   i++   poj 2533   incr   pre   

原文地址:https://www.cnblogs.com/yun-an/p/11108418.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!