1. 程式人生 > >CS Round50D min-races

CS Round50D min-races

ott 的人 org lar ini max const 覆蓋數 perm

Min Races

Time limit: 1000 ms
Memory limit: 256 MB

In a racing championship there are N racing drivers. The drivers are divided in K classes.

After a race, a driver is declared a winner if all the drivers that finish in front of him are from better classes (with smaller indices than his own).

As the main organiser of the championship, you can choose for each race which drivers are allowed to participate. Find the minimum number of races needed such that every driver is a winner at least once.

Standard input

The first line contains 2 integers N and K.

Each of the next N lines contains 2 integers a_i and b_i. The first integer a_i?? represents the class of driver i, while b_i is his place in a race with all the N drivers.

Standard output

Print the answer on the first line.

Constraints and notes

  • 1≤KN10?5??
  • There will be at least one driver from each class
  • The values bb will be a permutation from 1 to N.
題意:N人進行賽車比賽,其中他們被分為K組。在一場比賽中,如果一個人沒有被組別小於他的人排名高於他,他就被認為是獲勝。已知每個人能力的排名,求至少要進行多少場比賽才能讓每個人至少獲勝一場? 對bi進行排序後,不難發現這是一個求最小上升子序列覆蓋的問題。對此有一個定理:最小覆蓋數=最長不上升子序列長度。由是排序後跑一邊LIS即可。‘
#include<bits/stdc++.h>
using
namespace std; #define MAXN 100000+10 struct per{int a,b;}p[MAXN]; int n,k,d[MAXN]; bool cmp(per x,per y){return x.b<y.b;} int main(){ scanf("%d%d",&n,&k); for(int i=1;i<=n;i++)scanf("%d%d",&p[i].a,&p[i].b); sort(p+1,p+n+1,cmp); d[1]=p[1].a; int len=1; for(int i=2;i<=n;i++){ if(d[len]>=p[i].a)d[++len]=p[i].a; else{ int l=1,r=len,mid,ans=-1; while(l<=r){ mid=(l+r)>>1; if(d[mid]<p[i].a){ ans=mid; r=mid-1; } else l=mid+1; } d[ans]=p[i].a; } } printf("%d\n",len); return 0; }

CS Round50D min-races