1. 程式人生 > >LRJ入門經典-0907萬聖節的小L306

LRJ入門經典-0907萬聖節的小L306

原題

LRJ入門經典-0907萬聖節的小L306
難度級別:B; 執行時間限制:1000ms; 執行空間限制:256000KB; 程式碼長度限制:2000000B
試題描述

今天是萬聖節,小L同學開始了一年一度的討要糖果遊戲,但是在剛剛過去的比賽中小有成就的他打算給自己增加一點難度:如果沒有討到每一家的糖果就算輸。

已知小L共有n(n不大於10000)個鄰居,他們都在同一條街上(可以近似看成一條直線),第i個鄰居的座標是xi。L同學的媽媽會在一開始把他送到任意鄰居的門前。現在已知所有鄰居會在di時間後休息(休息以後不能再去打擾),求訪問完所有點的最短時間,如果無解輸出“No solution”。

輸入
輸入第一行為一個正整數表示n,接下來n行,每行兩個用空格隔開的數,分別表示第i個鄰居的位置和休息時間。
輸出
輸出一個數,表示最短時間,無解輸出“No solution”。
輸入示例
5
1 3
3 1
5 8
8 19
10 15
輸出示例
11

分析

程式碼

#include<iostream>
#include<cstring>
#include<algorithm>
#define INF 1073741824
using namespace std;
int dp[2][10001][2],n;
int a[10001],b[10001];
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i]>>b[i];
	for(int i=1;i<=n;i++) dp[0][i][0]=dp[1][i][1]=0;
	for(int k=1;k<n;k++)
	{
		for(int i=1;i+k<=n;i++)
		{
			int j=i+k,x,y;
			int I=(i%2)^1;
			dp[i%2][j][0]=dp[i%2][j][1]=INF;
			x=dp[i%2][j-1][1]+a[j]-a[j-1];y=dp[i%2][j-1][0]+a[j]-a[i];
			if(x>b[j]) x=INF;
			if(y>b[j]) y=INF;
			dp[i%2][j][1]=min(dp[i%2][j][1],min(x,y));
			//cout<<"i:"<<i<<"  j:"<<j<<"  o:1"<<"  x:"<<x<<"  y:"<<y<<"  dp:"<<dp[i%2][j][1]<<endl;
			x=dp[I][j][0]+a[i+1]-a[i];y=dp[I][j][1]+a[j]-a[i];
			if(x>b[i]) x=INF;
			if(y>b[i]) y=INF;
			dp[i%2][j][0]=min(dp[i%2][j][0],min(x,y));
			//cout<<"i:"<<i<<"  j:"<<j<<"  o:0"<<"  x:"<<x<<"  y:"<<y<<"  dp:"<<dp[i%2][j][0]<<endl<<endl;
		}
	}
	if(min(dp[1][n][0],dp[1][n][1])==INF) cout<<"No solution";
	else cout<<min(dp[1][n][0],dp[1][n][1]);
	return 0;
}