dp(0)

比赛前来一发

近期写的几个入门dp都不会的转移方程

p1280

在1~N的区间中有若干个任务,求出最大的空闲时间

反向递推 dp[i]为当前时间点的最大空闲时间

如果当前时间的任务数为0
\[dp[i] = dp[i+1] + 1\]
如果当前时间的任务数大于零
\[dp[i] = max(dp[i],dp[i+end[j]])\]
j取值为当前时间开始的所有任务

P1020 导弹拦截

第一问求最长不下降子序列,第二问求最长不上升子序列(后面不上升序列可以用当前系统拦截?上升了则需要新的系统)

dp[i]是长度为i的不下降子序列的最大结束点

如果当前a[i]<=dp[cur]

    dp[++cur] = a[i];

长度加1 结束点为a[i]

如果当前a[i]>dp[cur]

int l=0,r=cur;
int mid
{
    while(l<r)
    {
        mid = (l+r)>>1;
        if(dp[mid]>=a[i])   
            l = mid +1;
        else
            r = mid;
    }
    dp[l] = a[i];
}

二分长度(dp的值满足单调性) 更新dp值为a[i]

p1091

要求序列满足 $T_1<T_2\dotsT_i+1\dots>T_k $
求序列的最大长度

我们可以计算从左到右每个点的最长上升序列和从右到左每点的下降序列

对每个点的上升序列加下降序列最大减1即为答案

for(int i=1;i<=n;++i)
{
    for(int j=1;j<i;++j)
    {
        if(a[i]>a[j])
            dp[i] = max(dp[i],dp[j]+1;
    }
}

转载于:https://www.cnblogs.com/xxrlz/p/10555619.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值