luogu P3842 [TJOI2007]線段

有一個比較顯然的東西,就是你不管當前段走到哪裏,你下一行總是要走回去
也就是說,我們不管走到哪裏,與 當前到左右端點是等效的

然後就推出下面那個毒瘤式子就好了。。。

推薦畫圖來討論情況(一屏幕的式子(光速逃 ))

有點像那個關路燈(似乎是那題的弱化版)

#include<bits/stdc++.h>
#define MAXN 20005
using namespace std;

int n;
int l[MAXN],r[MAXN];
int f[MAXN][3];

void init(){
	cin>>n;
	memset(f , 0x7f , sizeof(f));
	for(int i = 1 ; i <= n ; i++)cin>>l[i]>>r[i];
	f[1][0] = l[1] - 1 + 2 * (r[1] - l[1]);
	f[1][1] = r[1] - 1;
}
//תÒÆÕâô³¤µÄÂï¡£¡£¡£¡£¡£ 
void solve(){
	for(int i = 2 ; i <= n ; i++){
		if(l[i - 1] <= l[i] && r[i - 1] >= r[i]){
			f[i][0] = min(f[i][0] , f[i - 1][0] + 1 + l[i] - l[i - 1] + 2 * (r[i] - l[i]));
			f[i][0] = min(f[i][0] , f[i - 1][1] + 1 + r[i - 1] - l[i]);
			f[i][1] = min(f[i][1] , f[i - 1][0] + 1 + r[i] - l[i -1]);	
			f[i][1] = min(f[i][1] , f[i - 1][1] + 1 + r[i - 1] - r[i] + 2 * (r[i] - l[i]));	
		}
		else if(l[i - 1] >= l[i] && r[i - 1] <= r[i]){
			f[i][0] = min(f[i][0] , f[i - 1][0] + 1 + (r[i] - l[i - 1]) * 2 + l[i - 1] - l[i]);
			f[i][0] = min(f[i][0] , f[i - 1][1] + 1 + (r[i] - r[i - 1]) + r[i] - l[i]);
			f[i][1] = min(f[i][1] , f[i - 1][0] + 1 + (l[i - 1] - l[i]) + r[i] - l[i]);
			f[i][1] = min(f[i][1] , f[i - 1][1] + 1 + (r[i - 1] - l[i]) * 2 + r[i] - r[i - 1]);		 
		}
		else if(r[i] <= l[i - 1]){
			f[i][0] = min(f[i][0] , f[i - 1][0] + 1 + l[i - 1] - l[i]);
			f[i][0] = min(f[i][0] , f[i - 1][1] + 1 + r[i - 1] - l[i]);
			f[i][1] = min(f[i][1] , f[i - 1][0] + 1 + l[i - 1] - r[i] + 2 * (r[i] - l[i]));
			f[i][1] = min(f[i][1] , f[i - 1][1] + 1 + r[i - 1] - r[i] + 2 * (r[i] - l[i]));
		}
		else if(l[i] >= r[i - 1]){
			f[i][0] = min(f[i][0] , f[i - 1][0] + 1 + l[i] - l[i - 1] + 2 * (r[i] - l[i]));
			f[i][0] = min(f[i][0] , f[i - 1][1] + 1 + l[i] - r[i - 1] + 2 * (r[i] - l[i]));
			f[i][1] = min(f[i][1] , f[i - 1][0] + 1 + r[i] - l[i - 1]);
			f[i][1] = min(f[i][1] , f[i - 1][1] + 1 + r[i] - r[i - 1]);
		}
		else if(l[i - 1] <= l[i] && r[i - 1] <= r[i]){
			f[i][0] = min(f[i][0] , f[i - 1][0] + 1 + 2 * (r[i] - l[i]) + l[i] - l[i - 1]);
			f[i][0] = min(f[i][0] , f[i - 1][1] + 1 + 2 * (r[i] - r[i - 1]) + r[i - 1] - l[i]);
			f[i][1] = min(f[i][1] , f[i - 1][0] + 1 + r[i] - l[i - 1]);
			f[i][1] = min(f[i][1] , f[i - 1][1] + 1 + 2 * (r[i - 1] - l[i]) + r[i] - r[i - 1]);
		}
		else if(l[i - 1] >= l[i] && r[i - 1] >= r[i]){
			f[i][0] = min(f[i][0] , f[i - 1][0] + 1 + 2 * (r[i] - l[i - 1]) + l[i - 1] - l[i]);
			f[i][0] = min(f[i][0] , f[i - 1][1] + 1 + r[i - 1] - l[i]);
			f[i][1] = min(f[i][1] , f[i - 1][0] + 1 + 2 * (l[i - 1] - l[i]) + r[i] - l[i - 1]);
			f[i][1]	= min(f[i][1] , f[i - 1][1] + 1 + 2 * (r[i] - l[i]) + r[i - 1] - r[i]);		
		}
	}
	cout<<min(f[n][0] + (n - l[n]) , f[n][1] + (n - r[n]))<<endl;
}

int main(){
	init();
	solve();
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章