动态规划

1.动态规划既多阶段决策问题:将一个问题的求解过程分为多个相互影响相互联系的小过程,在每个小过程中做最优处理,构成一个最优决策序列,从中选取最优决策。

2.动态规划基本模型:

¢  问题具有多阶段决策的特征。
¢  每一阶段都有相应的“状态”与之对应,描述状态的量称为“状态变量”。
¢每一阶段都面临一个决策,选择不同的决策将会导致下一阶段不同的状态。
¢每一阶段的最优解问题可以递归地归结为下一阶段各个可能状态的最优解问题,各子问题与原问题具有完全相同的结构。
3.经典例题:最长上升子序列
 

      问题描述一个数的序列bi,当b1 < b2 < ... < bS的时候,我们称这个序列是上升的。对于给定的一个序列(a1, a2, ..., aN),我们可以得到一些上升的子序列(ai1, ai2, ..., aiK),这里1 <= i1 < i2 <... <iK <= N

       比如,对于序列(1, 7, 3, 5, 9, 4, 8),有它的一些上升子序列,如(1,7), (3, 4, 8)等等。这些子序列中最长的长度是4,比如子序列(1,3, 5, 8).

你的任务,就是对于给定的序列,求出最长上升子序列的长度
 

输入数据:输入的第一行是序列的长度N(1 <= N <= 1000)。第二行给出序列中的N 个整数,这些整数的取值范围都在010000

输出要求最长上升子序列的长度。

分析:求以akk=1,2, 3…N)为终点的最长上升子序列的长度”是个好的子问题。

假定MaxLen (k)表示以ak做为“终点”的最长上升子序列的长度,那么:

MaxLen(1) = 1

MaxLen(k) = Max { MaxLen (i)1<i< k ai < akk1} + 1

代码:

#include<bits/stdc++.h>
using namespace std;
int a[100010],maxlen[100010];
//a存储输入的n个数
//maxlen[i]记录以a[i]结尾的最长上升子序列长度
int main()
{
    int n,max,ans=-1;
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    maxlen[1]=1;
    //以a[1]结尾的最长上升子序列长度为1,以maxlen[1]开始递归表示maxlen[i]
    for(int i=2;i<=n;i++)
    {
        max=0;
        for(int j=1;j<i;j++)//枚举所有a[i]以前的上升子序列
            if(a[j]<a[i])//保证上升
                max=max>maxlen[j]?max:maxlen[j];//取最长上升子序列
        maxlen[i]=max+1;//求以a[i]结尾的最长上升子序列,并放入最优集maxlen
    }
    for(int i=1;i<=n;i++)
    {
        ans=ans>maxlen[i]?ans:maxlen[i];//求最优集中的最优解
    }
    cout<<ans<<endl;
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值