动态规划5:求解最多航线问题(应用了最长子序列知识)
2014-09-11 12:14
337 查看
这道题应用了动态规划的相关的知识来解决,主要是应用到了最长上升子序列的知识来解决,下面引述动态规划32讲中的相关解释来解决该问题:
【问题分析】
这道题目相对来说思考难度较高,从字面意义上看不出问题的本质来,有点无法下手的感觉。
这里我给大家推荐两种思考这类问题的方法。
法一:寻找规律法(我前面总结提到的第 3 个方法)
寻找规律自然要推几组数据,首先当然要从样例入手;
仔细观察上图:红色航线是合法的,那么他们满足什么规律呢?
C1 C2 C3 C4
北岸红线的端点: 4 9 15 17
南岸红线的端点: 2 8 12 17
D1 D2 D3 D4
不难看出无论线的斜率如何,都有这样的规律:
C1<C2<C3<C4 且 D1<D2<D3<D4
如果我们把输入数据排升序,问题变抽象为:
在一个序列(D)里找到最长的序列满足 DI<DJ<Dk……且 i<j<k
这样的话便是典型的最长非降子序列问题了。。。。
法二:边界条件法(我前面总结提到的第 4 个方法)
边界法其实就是把数据往小了缩,显然 N=1 是答案是 1。N=2 时呢?
考虑这样一组数据:
N=2
C1 C2
D1 D2
当 C1< C2 时,如果D1>D2 那么一定会相交,反之则不会相交。
当 C1> C2 时,如果D1<D2 那么一定会相交,反之则不会相交。
N=3
C1 C2 C3
D1 D2 D3
……
其实不用在推导 N=3 了,有兴趣的可以推导去。看 N=2 时就能得出:
对于任意两条航线如果满足 Ci<Cj 且Di<Dj 则两条航线不相交。这样的话要想在一个序列里
让所有的航线都不相交那比然满足, C1<C2<C3…Cans 且 D1<D2<D3…<Dans ,也就是将 C 排
序后求出最长的满足这个条件的序列的长度就是解。
这样分析后显然是一个最长非降子序列问题。
复杂度:排序可以用 O(nlogn)的算法,求最长非降子序列时间复杂度是 O(n2).
总复杂度为 O(n2).
CODE:
//2014年9月11日11:53:19
//author:BGY
#include<stdio.h>
#include<climits>
#include<algorithm>
#include<stack>
#include<iostream>
#include<cmath>
#include<set>
#include<vector>
#include<map>
#include<queue>
#include<string.h>
using namespace std;
const int maxn=6500;
typedef struct node
{
int north;
int south;
}node;
int cmp(node a, node b)
{
return a.north<b.north;
}
node a[maxn];
int opt[maxn];
int main(void)
{
int n,m;
while(scanf("%d %d",&n,&m)!=EOF)
{
int t;
scanf("%d",&t);
for(int i=1;i<=t;i++)
{
scanf("%d %d",&a[i].north,&a[i].south);
}
sort(a+1,a+t+1,cmp);//把他们按照北岸的那个点的顺序来排列;
a[0].north=INT_MIN;
a[0].south=INT_MIN;//初始化第一个为最小的
memset(opt,0,sizeof(opt));//最小化
for(int i=1;i<=t;i++)
{
for(int j=0;j<i;j++)
{
if(a[i].south>a[j].south&&opt[i]<opt[j]+1)
{
opt[i]=opt[j]+1;
}
}
}//求出opt
int c=INT_MIN;
//找出最大的那个,就是说明了他必须具备的性质
for(int i=1;i<=t;i++)
{
if(opt[i]>c) c=opt[i];
}
cout<<c<<endl;
}
return 0;
}
COME ON
相关文章推荐
- 算法笔记:动态规划求解最长子序列问题
- 动态规划解决最长子序列问题
- 动态规划之LCS最长子序列问题
- 【C语言】最长子序列问题求解
- 动态规划求解最多有几种方案求解硬币找零问题
- 动态规划之最长子序列问题
- 动态规划之最长子序列问题
- 动态规划之最长子序列问题
- 动态规划在求解传递闭包问题中的应用(JAVA)--Warshell算法
- 动态规划—最长子序列问题
- 用动态规划法求解生物信息学中DNA序列比对的问题 (交叉学科应用实验)
- _____________________________________动态规划之最长子序列问题______1:两个序列中的______________________________________
- 动态规划求解最长公共子序列问题
- 关于最长递增子序列问题的求解(LIS)
- 最大子序列问题及其求解----C 语言学习
- 最长子序列问题之系列一
- 关于最长递增子序列问题的求解(LIS)
- 数字序列加入+,*运算符后取得最大值问题; 动态规划;打破传统从决策入手思想;找出问题的特有性质;从例子入手找特点;
- Java【多线程知识总结(7)】多线程同步问题-关于synchronized代码块和synchronized方法的应用
- 用动态规划求解0-1背包问题