【简单DP】P3842 [TJOI2007]线段

P3842 [TJOI2007]线段 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

 

题意:

思路:

考虑线性DP

把行作为阶段去DP

然后观察样例可知有一个很显然的结论:为了保证路径最小,要不是从左端点下去的,要不是从右端点下去的

 

那么可以这样设计状态:

设dp[i][0]为第i行,从左端点下去的最短路径

dp[i][1]为第i行,从右端点下去的最短路径

然后就能转移了

当前从左端点下去的,上一行可能从左/右端点下来,讨论一下即可

注意第一行要初始化

Code:

#include <bits/stdc++.h>

#define int long long

using namespace std;

const int mxn=2e4+10;

int N;
int L[mxn],R[mxn];
int dp[mxn][2];

void solve(){
    cin>>N;
    for(int i=1;i<=N;i++) cin>>L[i]>>R[i];
    dp[1][0]=R[1]-1+1+R[1]-L[1];
    dp[1][1]=R[1]-1+1;
    for(int i=2;i<=N;i++){
        dp[i][0]=min(dp[i-1][0]+abs(R[i]-L[i-1])+1+R[i]-L[i],dp[i-1][1]+abs(R[i-1]-R[i])+1+R[i]-L[i]);
        dp[i][1]=min(dp[i-1][0]+abs(L[i-1]-L[i])+1+R[i]-L[i],dp[i-1][1]+abs(R[i-1]-L[i])+1+R[i]-L[i]);
    }
    cout<<dp[N][1]+N-(R[N]+1)<<'\n';
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int __=1;//cin>>__;
    while(__--)solve();return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值