TJOI2007--线段

题目传送门
image
image

代码

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

posted @ 2025-09-18 14:32  mark2025  阅读(5)  评论(0)    收藏  举报