题目传送门
代码
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=2e4+10;
int n;
int l[N],r[N],len[N];
int dp[N][2];
//dp[i][0]表示停留在本行左端点
//那么就要到右端点在再回到左端点
//dp[i][1]表示停留到本行右端点
//就从本行左端点到右端点
int main()
{ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);cin>>n;//for(int i=1;i<=n;i++){cin>>l[i]>>r[i];len[i]=r[i]-l[i]+1;}dp[1][0]=r[1]+r[1]-l[1]-1;dp[1][1]=r[1]-1;//停留在本行右端点可能从上一行左端点来//也可能从上一行右端点来 取最小值//停留在本行左端点可能从上一行左端点来//也可能从上一行右端点来 取最小值//最后得到f[n][0]停留在左端点//或f[n][1]停留在右端点 // 两种情况到n n的值 取最小值 for(int i=2;i<=n;i++){dp[i][0]=min(dp[i-1][0]+abs(l[i-1]-r[i])+len[i],dp[i-1][1]+abs(r[i-1]-r[i])+len[i]) ;dp[i][1]=min(dp[i-1][0]+abs(l[i-1]-l[i])+len[i],dp[i-1][1]+abs(r[i-1]-l[i])+len[i] );} int res=min(dp[n][0]+n-l[n],dp[n][1]+n-r[n]);cout<<res;return 0;
}