题目的意思是,两行城市,从左到右为1,2,3……n个城市。上面的下面的城市要与上面某个的城市相连,在不出现相交的情况下,最多可以连多少条。
知道了题意,就知道了应该用DP来做。
这一题,数据量比较大,用普通的DP,时间复杂度为N^2,会超时,我们应该用另一种DP方法,时间复杂度为nlogn。
nlogn的DP的思路大概就是给你一个数,插到一个数组中,该位置已存在,就覆盖它。也就是可以用二分查找提高效率。
注意:输出的时候,要注意英语的单复数。。。
下面的是AC的代码:
#include <iostream> #include <cstdio> #include <cstring> using namespace std; int n, dp[500005], a[500005]; int finds(int num, int len) //二分查找num的位置并返回 { int left, right, mid; left = 1; right = len; mid = (left + right) / 2; while(left <= right) { if(dp[mid] == num) return mid; else if(dp[mid] < num) left = mid + 1; else right = mid - 1; mid = (left + right) / 2; } return left; } int main() { int i, j, k, count = 0; while(scanf("%d", &n) != EOF) { for(i = 0; i < n; i++) //输入poor城市对应的rich城市 { scanf("%d%d", &j, &k); a[j] = k; //a数组为第j个poor城市对应第k个rich城市 } memset(dp, 0, sizeof(dp)); dp[1] = a[1]; //插入一个数 int len = 1; //数组长度为1 for(i = 2; i <= n; i++) { j = finds(a[i], len); //查找剩下的poor城市对应的rich城市在数组的位置 dp[j] = a[i]; //覆盖 if(len < j) //更新长度 { len = j; } } printf("Case %d:\n", ++count); //输出 if(len == 1) printf("My king, at most %d road can be built.\n", len); else printf("My king, at most %d roads can be built.\n", len); printf("\n"); } return 0; }
杭电ACM1025——Constructing Roads In JGShining's Kingdom
原文地址:http://blog.csdn.net/qq_25425023/article/details/45463127