dp学习笔记3

今天学了求最长递增子序列的O(n*log(n))算法。。。

View Code
 1 /*
 2 【问题描述】
 3 PALMIA国家被一条河流分成南北两岸,南北两岸上各有N个村庄。北岸的每一个村庄有一个唯一的朋友在南岸,且他们的朋友村庄彼此不同。
 4 每一对朋友村庄想要一条船来连接他们,他们向政府提出申请以获得批准。由于河面上常常有雾,政府决定禁止船只航线相交(如果相交,则很可能导致碰船)。
 5 你的任务是编写一个程序,帮助政府官员决定批准哪些船只航线,使得不相交的航线数目最大。
 6 */
 7 /*
 8 测试样例:
 9 30 4
10 7
11 22 4
12 2 6
13 10 3
14 15 12
15 9 8
16 17 17
17 4 2
18 正确输出:
19 4
20 */
21 /*
22 于任意两条航线如果满足Ci<Cj 且Di<Dj 则两条航线不相交。
23 这样的话要想在一个序列里让所有的航线都不相交那比然满足,C1<C2<C3…Cans且D1<D2<D3…<Dans ,
24 也就是将C排序后求出最长的满足这个条件的序列的长度就是解
25 */
26 ///以下是n*log(n)的做法。。。
27 #include<iostream>
28 #include<algorithm>
29 const int N=5007;
30 using namespace std;
31 
32 struct Node{
33     int x,y;
34 }node[N];
35 int dp[N];
36 
37 int cmp(Node &a,Node &b){
38     if(a.x != b.x)
39         return a.x<b.x;
40     return a.y<b.y;
41 }
42 
43 int Search(int dp[],int len,int num){
44     int low=1,high=len;
45     while(low<=high){
46         int mid=(low+high)/2;
47         if(num==dp[mid])return mid;
48         else if(num<dp[mid])high=mid-1;
49         else low=mid+1;
50     }
51     return low;
52 }
53 
54 int main(){
55     int lx,ly;
56     while(~scanf("%d%d",&lx,&ly)){
57         int n;
58         scanf("%d",&n);
59         for(int i=1;i<=n;i++){
60             scanf("%d%d",&node[i].x,&node[i].y);
61         }
62         sort(node+1,node+n+1,cmp);
63         dp[0]=-1,dp[1]=node[1].y;
64         int len=1;
65         //n*log(n)算法求最长非下降子序列
66         for(int i=2;i<=n;i++){
67             int pos=Search(dp,len,node[i].y);
68             dp[pos]=node[i].y;
69             if(pos>len)len++;
70         }
71         printf("%d\n",len);
72     }
73     return 0;
74 }

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值