hdu1025——Constructing Roads In JGShining's Kingdom

Constructing Roads In JGShining's Kingdom

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 16024    Accepted Submission(s): 4572


Problem Description
JGShining's kingdom consists of 2n(n is no more than 500,000) small cities which are located in two parallel lines.

Half of these cities are rich in resource (we call them rich cities) while the others are short of resource (we call them poor cities). Each poor city is short of exactly one kind of resource and also each rich city is rich in exactly one kind of resource. You may assume no two poor cities are short of one same kind of resource and no two rich cities are rich in one same kind of resource.

With the development of industry, poor cities wanna import resource from rich ones. The roads existed are so small that they're unable to ensure the heavy trucks, so new roads should be built. The poor cities strongly BS each other, so are the rich ones. Poor cities don't wanna build a road with other poor ones, and rich ones also can't abide sharing an end of road with other rich ones. Because of economic benefit, any rich city will be willing to export resource to any poor one.

Rich citis marked from 1 to n are located in Line I and poor ones marked from 1 to n are located in Line II.

The location of Rich City 1 is on the left of all other cities, Rich City 2 is on the left of all other cities excluding Rich City 1, Rich City 3 is on the right of Rich City 1 and Rich City 2 but on the left of all other cities ... And so as the poor ones.

But as you know, two crossed roads may cause a lot of traffic accident so JGShining has established a law to forbid constructing crossed roads.

For example, the roads in Figure I are forbidden.



In order to build as many roads as possible, the young and handsome king of the kingdom - JGShining needs your help, please help him. ^_^
 

Input
Each test case will begin with a line containing an integer n(1 ≤ n ≤ 500,000). Then n lines follow. Each line contains two integers p and r which represents that Poor City p needs to import resources from Rich City r. Process to the end of file.
 

Output
For each test case, output the result in the form of sample.
You should tell JGShining what's the maximal number of road(s) can be built.
 

Sample Input
  
2 1 2 2 1 3 1 2 2 3 3 1
 

Sample Output
  
Case 1: My king, at most 1 road can be built. Case 2: My king, at most 2 roads can be built.
Hint
Huge input, scanf is recommended.
 

Author
JGShining(极光炫影)
 

Recommend
We have carefully selected several similar problems for you:   1024  1074  1080  1059  1160 
 

转化很简单,对左边坐标从小到大排序,如果左边相等,再按右边从小到大排序,这样之后,左边一定有序,如果不能出现交叉的路,那么就是在右边寻找一个最长的不下降子序列,但是O(n^2)的做法会TLE

于是去网上学了O(logn)的做法,这里简单介绍下


我们假设所求序列放在数组d里,显然d是单调不下降的
对于当前尝试的a[i],如果a[i]比d[len]大或者相等,那么放入a[i],显然会得到一个更长的序列;如果a[i]小于d[len],就需要通过二分查找,查到大于a[i]的最小的数并且替换,为什么要这么做呢,我们可以在不减小序列长度的情况下,缩小序列元素的值,使得它更有可能纳入后面的元素从而使整个最长不下降序列的长度更长
对了,如果不是修改大于a[i]的最小的数,而是修改其他更大的数,那么就会导致d数组不是有序的,从而破坏了d的结构,那就无法求出最长不下降序列的长度了
还有一点要注意,最后求出来的d数组不是所求的最长不下降序列,例如  2 5 1,最后在d数组里的是 1 5,而真正的最长不下降序列是2 5

#include<map>
#include<set>
#include<list>
#include<stack>
#include<vector>
#include<queue>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>

using namespace std;

struct node
{
    int l, r;
}road[500010];

int d[500010];
int arr[500010];

int cmp(node a, node b)
{
    if(a.l != b.l)
        return a.l < b.l;
    return a.r < b.r;
}

int main()
{
    int n;
    int icase = 1;
    while(~scanf("%d", &n))
    {
        for(int i = 0; i < n; i++)
        {
            scanf("%d%d", &road[i].l, &road[i].r);
        }    
        sort(road, road + n, cmp);
        for(int i = 0; i < n; i++)
            arr[i] = road[i].r;
//      dp[i] = max(dp[j])+ 1
//       O(n^2)  TlE
/*        for(int i = 0; i < n; i++)
        {
            for(int j = 0; j < i; j++)
            {
                if(arr[i] > arr[j] && dp[i] < dp[j] + 1)
                    dp[i] = dp[j] + 1;
            }
            ans = max(ans, dp[i]);
        } 
*/
		memset( d, 0, sizeof(d) );
		int len = 0, l, mid, r;
		for(int i = 0; i < n; i++)
		{
			if(d[len] <= arr[i])
				d[++len] = arr[i];
			else
			{
				//二分查比arr[i]大的第一个数
			 	l = 1;
			 	r = len;
			 	int ans;
			 	while(l <= r)
			 	{
			 		mid = (l + r) >> 1;
	 				if(d[mid] > arr[i])
	 				{
				 		r = mid - 1;
				 		ans = mid;
				 	}
				 	else
				 	{
	 					l = mid + 1;
	 				}
	 			}
	 			d[ans] = arr[i];//替换 
			}
		}
        printf("Case %d:\n", icase++);
        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;
}



【SCI复现】基于纳什博弈的多微网主体电热双层共享策略研究(Matlab代码实现)内容概要:本文围绕“基于纳什博弈的多微网主体电热双层共享策略研究”展开,结合Matlab代码实现,复现了SCI级别的科研成果。研究聚焦于多个微网主体之间的能源共享问题,引入纳什博弈理论构建双层优化模型,上层为各微网间的非合作博弈策略,下层为各微网内部电热联合优化调度,实现能源高效利用与经济性目标的平衡。文中详细阐述了模型构建、博弈均衡求解、约束处理及算法实现过程,并通过Matlab编程进行仿真验证,展示了多微网在电热耦合条件下的运行特性和共享效益。; 适合人群:具备一定电力系统、优化理论和博弈论基础知识的研究生、科研人员及从事能源互联网、微电网优化等相关领域的工程师。; 使用场景及目标:① 学习如何将纳什博弈应用于多主体能源系统优化;② 掌握双层优化模型的建模与求解方法;③ 复现SCI论文中的仿真案例,提升科研实践能力;④ 为微电网集群协同调度、能源共享机制设计提供技术参考。; 阅读建议:建议读者结合Matlab代码逐行理解模型实现细节,重点关注博弈均衡的求解过程与双层结构的迭代逻辑,同时可尝试修改参数或扩展模型以适应不同应用场景,深化对多主体协同优化机制的理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值