DPday4 线性状态DP luogu P1020 [NOIP1999 普及组] 导弹拦截

luogu P1020 [NOIP1999 普及组] 导弹拦截

题目链接
难度:普及/提高-

本篇题解没有写完,今天先这样吧!

一. 动态规划回顾

动态规划是用来解决多阶段决策问题的。

多阶段决策问题:如果一类活动过程可以分为若干个互相联系的阶段,在每一个阶段都需作出决策(采取措施),一个阶段
的决策确定以后,常常影响到下一个阶段的决策,从而就完全确定了一个过程的活动路线,则称它为多阶段决策问题。
动态规划通过一个决策过程表示一个问题,决策过程的各个阶段的关系可以是线性的,也可以是更复杂的函数关系。

二. 动态规划的分类

动态规划一般可分为线性动规,区域动规,树形动规,背包动规四类。
举例:
线性动规:拦截导弹,合唱队形,挖地雷,建学校,剑客决斗等;
区域动规:石子合并, 加分二叉树,统计单词个数,炮兵布阵等;
树形动规:贪吃的九头龙,二分查找树,聚会的欢乐,数字三角形等;
背包问题:01背包问题,完全背包问题,分组背包问题,二维背包,装箱问题,挤牛奶等

三. 线性状态动态规划

线性状态动态规划问题是动态规划问题中最常见,具体表现为动态规划的决策过程中,不同阶段的关系是线性的,状态量也是线性的。常见题型为序列的处理:最长上升子序列、最长公共子序列、编辑距离等等。

无论线性 dp 的状态表示上是一维的还是多维的,都是线性上的递推。dp 的阶段沿着各个维度线性增长,从一个或多个边界点开始,有方向地向整个状态空间转移、拓展。最后每个状态上都保留了以自身为 “目标” 的子问题的最优解。

代码:

1. O ( n 2 ) O(n^2) O(n2)复杂度:

#include <bits/stdc++.h>
#define LEN 10001
using namespace std;
long h[LEN] = {0};
long dp[LEN];
int main(){
    int n = 0;
    while(scanf("%ld",&h[n])!=EOF){
        dp[n] = 1;
        n++;
    }
    long sum = 0;
    for (int i = 0; i < n;i++)
    {
        for (int j = 0; j < i;j++)
        {
            if(h[j]>=h[i])
                dp[i] = max(dp[j] + 1, dp[i]);
        }
    }
    for (int i = 0; i < n;i++)
        sum = max(dp[i],sum);
    cout << sum << endl;
    sum = 0;
    for (int i = 0; i < n;i++)
    {
        dp[i] = 1;
        for (int j = 0; j < i;j++)
        {
            if(h[j]<h[i])
                dp[i] = max(dp[j] + 1, dp[i]);
        }
    }
    for (int i = 0; i < n;i++)
        sum = max(dp[i],sum);
    cout << sum << endl;
    return 0;
}

2. O ( n l o g n ) O(nlogn) O(nlogn)复杂度:

3. 树状数组解法:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值