hdu 1025 Constructing Roads In JGShining's Kingdom
2016-05-02 15:24
239 查看
题目大意
题目挺长的,有点不容易读懂,意思就是给你2n个城市,一班为poor city,一半为rich city,每一个poor city需要对应的rich city提供相对应缺少的资源。这样一一对应,因为要建道路,并且要建足够多的道路,同时道路之间不能有相交情况。题目分析
因为每一个poor city的编号为1~n,每一个下标对应一个rich city,需要修建足够多的道路并且道路不想交,转化一下大家会发现,就是求以poor city的编号为数组本身下标的最长递增子序列长度。需要注意的是,求最长递增子序列长度的朴素算法时间复杂度为(n*n),当n达到40000的时候就会TLE,因此这里我们需要2分查找使时间复杂度为O(n*log n)。#include <cstdio> #include <cstring> #include <algorithm> #include <iostream> using namespace std; const int maxn = 500005; int a[maxn],g[maxn],dp[maxn]; int main() { int n,kase = 0; while(scanf("%d", &n) != EOF) { int x,y; for(int i = 1; i <= n; i++) //因为下标必定为1~n并且不会重复,所以直接这样写就不用写结构体并且sort. { scanf("%d %d", &x, &y); a[x] = y; } for(int i = 1; i < maxn; i++) g[i] = maxn; for(int i = 1; i <= n; i++) { int k = lower_bound(g+1, g+n+1, a[i]) - g; //lower_bound()用于查找大于或者等于a[i]的g数组的地址 dp[i] = k; g[k] = a[i]; //更新g[k]的值 } int ans = 0; for(int i = 1; i <= n; i++) //找到最长的递增子序列长度 ans = max(ans, dp[i]); if(ans == 1) //输出有坑,注意只有一条道路是,road后面不加s,并且输出之后要添加空行 printf("Case %d:\nMy king, at most %d road can be built.\n\n", ++kase, ans); else printf("Case %d:\nMy king, at most %d roads can be built.\n\n", ++kase, ans); } return 0; }
相关文章推荐
- Java中final关键字的用法
- Is the server running on host “localhost” (::1) and accepting TCP/IP connections on port 5432?
- 解决使用pip安装lxml包报错问题
- JS学习6(函数表达式)
- 用HTML 5实现爱心小鱼的游戏
- 定量分析与print跟踪在代码分析中的运用
- 开源新闻速递(160502):Arch Linux 2016.05.01 发布
- 48-Merge Sorted Array
- 学生信息管理系统总结整理
- redis安装
- spec cpu2006 working set size
- 也许你的种子永远不会开花,因为他是一棵参天大树
- UVa 10763 Foreign Exchange
- 安卓开发之java基础笔记【3】
- spring路径通配符
- 码农小汪-Spring MVC-强大的数据绑定1
- 【BZOJ4576】【BZOJ4580】【Usaco2016 Open】262144 贪心
- 第七周项目2
- Android中对内存和外存的读写
- PHP加密代码