題目背景 快noip了,yyy很緊張! 題目描述 現在各大oj上有n個比賽,每個比賽的開始、結束的時間點是知道的。 yyy認為,參加越多的比賽,noip就能考的越好(假的) 所以,他想知道他最多能參加幾個比賽。 由於yyy是蒟蒻,如果要參加一個比賽必須善始善終,而且不能同時參加2個及以上的比賽。 輸 ...
題目背景
快noip了,yyy很緊張!
題目描述
現在各大oj上有n個比賽,每個比賽的開始、結束的時間點是知道的。
yyy認為,參加越多的比賽,noip就能考的越好(假的)
所以,他想知道他最多能參加幾個比賽。
由於yyy是蒟蒻,如果要參加一個比賽必須善始善終,而且不能同時參加2個及以上的比賽。
輸入輸出格式
輸入格式:第一行是一個整數n ,接下來n行每行是2個正整數ai,bi(ai<bi),表示比賽開始、結束的時間。
輸出格式:一個整數最多參加的比賽數目。
輸入輸出樣例
輸入樣例#1:3 0 2 2 4 1 3輸出樣例#1:
2
說明
對於20%的數據,n≤10;
對於50%的數據,n≤1000;
對於70%的數據,n≤100000;
對於100%的數據,n≤1000000,0≤ai<bi≤1000000。
p[i]表示第i個時間點存在的比賽是從p[i]開始的,假如有兩組比賽的時間是相同的,那我們顯然希望得到p[i]較大的那組,就用較大的那個起始時間來替換p[i]
如此預處理之後,用f[i]表示到第i個時間點位置最多能參加幾場比賽假如對於i存在一個p[i],那就對f[i]取f[i-1](不參加比賽)和f[p[i]](參加比賽)之中的最大值
問題最終的答案就是f[1~maxint of endingtime]的最大值
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 using namespace std; 6 void read(int & n) 7 { 8 char c='+';int x=0;bool flag=0; 9 while(c<'0'||c>'9') 10 { 11 c=getchar(); 12 if(c=='-')flag=1; 13 } 14 while(c>='0'&&c<='9') 15 x=x*10+c-48,c=getchar(); 16 flag==1?n=-x:n=x; 17 18 } 19 const int MAXN=1000001; 20 int n; 21 int dp[1000001];// dp[i][0]表示第i天能獲得多少馬克 22 // dp[i][1]表示第i天能獲得多少美元 23 int p[MAXN]; 24 struct node 25 { 26 int bg,ed; 27 }a[MAXN]; 28 int main() 29 { 30 read(n); 31 memset(p,-1,sizeof(p)); 32 int maxt=0; 33 for(int i=1;i<=n;i++) 34 { 35 read(a[i].bg),read(a[i].ed); 36 p[a[i].ed]=max(p[a[i].ed],a[i].bg); 37 maxt=max(maxt,a[i].ed); 38 } 39 int ans=0; 40 for(int i=0;i<=maxt;i++) 41 { 42 if(p[i]!=-1) 43 dp[i]=max(dp[i-1],dp[p[i]]+1); 44 else 45 dp[i]=dp[i-1]; 46 ans=max(ans,dp[i]); 47 } 48 printf("%d",ans); 49 return 0; 50 }