TJOI2007--线段
代码
点击查看代码
#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;
}



浙公网安备 33010602011771号