题意:在RichCity与PoorCity之间造若干条路,要求路的两边的城市序号要相同,两种城市分别按任意顺序排列在两条直线上,求最多能造几条路
链接:http://acm.hdu.edu.cn/showproblem.php?pid=1025
思路:最长上升子序列问题,因为数据范围较大,所以需要用nlogn的算法解决,通过二分法查找dp序列中的最长上升序列,并进行替换
注意点:当子序列长度与road与roads关系,子序列长度为1时输出road,长度大于1时输出roads
以下为AC代码:
Run ID | Submit Time | Judge Status | Pro.ID | Exe.Time | Exe.Memory | Code Len. | Language | Author |
12831192 | 2015-01-28 16:29:46 | Accepted | 1025 | 608MS | 5124K | 1830 B | G++ | luminous11 |
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <deque>
#include <list>
#include <cctype>
#include <algorithm>
#include <climits>
#include <queue>
#include <stack>
#include <cmath>
#include <map>
#include <set>
#include <iomanip>
#include <cstdlib>
#include <ctime>
#define ll long long
#define ull unsigned long long
#define all(x) (x).begin(), (x).end()
#define clr(a, v) memset( a , v , sizeof(a) )
#define pb push_back
#define mp make_pair
#define read(f) freopen(f, "r", stdin)
#define write(f) freopen(f, "w", stdout)
using namespace std;
const double pi = acos(-1);
int num[500005];
int ans[500005];
void binarySearch( int len, int x ){
int l = 0;
int r = len;
int cnt = 0;
while ( l <= r ){
int m = ( l + r ) >> 1;
if ( x > ans[m] )l = m + 1;
else r = m - 1;
}
ans[l] = x;
}
int main()
{
ios::sync_with_stdio( false );
int n;
int ncase = 1;
while ( cin >> n ){
int a, b;
memset ( num, 0, sizeof ( num ) );
memset ( ans, 0, sizeof ( ans ) );
for ( int i = 0; i < n; i ++ ){
cin >> a >> b;
num[a] = b;
}
int cnt = 0;
ans[cnt] = num[1];
for ( int i = 2; i <= n; i ++ ){
if ( num[i] > ans[cnt] ){
ans[++cnt] = num[i];
}
else{
binarySearch( cnt, num[i] );
}
}
cout << "Case " << ncase ++ << ":" << endl;
if ( cnt )
cout << "My king, at most " << cnt + 1 << " roads can be built." << endl << endl;
else
cout << "My king, at most " << cnt + 1 << " road can be built." << endl << endl;
}
return 0;
}