题目:
X轴上有N条线段,每条线段包括1个起点和终点。线段的重叠是这样来算的,[10 20]和[12 25]的重叠部分为[12 20]。
给出N条线段的起点和终点,从中选出2条线段,这两条线段的重叠部分是最长的。输出这个最长的距离。如果没有重叠,输出0。
思路:
1、暴力计算
依次计算两两线段之间的重叠长度,但复杂度太高 (ps:可能我的第一反应就是暴力计算,以后多想想)
2、动态规划
假设S[n]表示n条线段中最长重叠距离,最长重叠距离只与两条线段有关,那么考虑两种情况:
1. 最长重叠距离与第n条线段无关,则最长重叠距离存在于前n-1条线段中,即S[n]=S[n-1];
2. 最长重叠距离与第n条线段有关,则最长重叠距离为第n条线段与前面n-1条线段中的最大重叠距离者,S[n]=max(overlap(segment[n],segment[i])), i=1....n-1
因此得到状态转移方程:
S[n]=0; n<=1
S[2]=overlap(segment[0],segment[1])
S[n]=max(S[n-1],max(overlap(segment[n],segment[i]))) for i in 0---n-1
代码:
动态规划:
/*
X轴上有N条线段,每条线段包括1个起点和终点。线段的重叠是这样来算的,[10 20]和[12 25]的重叠部分为[12 20]。
给出N条线段的起点和终点,从中选出2条线段,这两条线段的重叠部分是最长的。输出这个最长的距离。如果没有重叠,输出0。
*/
/*
*思路:假设S[n]表示n条线段中最长重叠距离,最长重叠距离只与两条线段有关,那么考虑两种情况:
1. 最长重叠距离与第n条线段无关,则最长重叠距离存在于前n-1条线段中,即S[n]=S[n-1];
2. 最长重叠距离与第n条线段有关,则最长重叠距离为第n条线段与前面n-1条线段中的最大重叠距离者,S[n]=max(overlap(segment[n],segment[i])), i=1....n-1
因此得到状态转移方程:
S[n]=0; n<=1
S[2]=overlap(segment[0],segment[1])
S[n]=max(S[n-1],max(overlap(segment[n],segment[i]))) for i in 0---n-1
*/
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
typedef struct {
int start;
int end;
}segment;
void displayOne(const segment &s1)
{
cout << "[" << s1.start << "," << s1.end << "] ";
}
void displayAll(const vector<segment>segs) {
for (int i = 0; i < segs.size(); i++)
displayOne(segs[i]);
cout << endl;
}
bool isShorter(const segment &s1, const segment &s2);
int commonSegment(const segment &seg_a, const segment &seg_b);
int findLongestSegment(const vector <segment> &segments, int size);
int main()
{
int n, start, end;
cout << "please input the numbers: ";
while (cin >> n)
{
vector<segment>segments(n);
for (int i = 0; i < n; i++)
{
start = rand() % 30;
end = start + rand() % 30;
segments[i].start = start;
segments[i].end = end;
}
int maxlen = findLongestSegment(segments, n);
displayAll(segments);
cout << "the maxlen is " << maxlen << endl;
cout << endl << "please input the numbers of segments:" ;
}
system("pause");
}
int commonSegment(const segment &seg_a, const segment &seg_b)
{
segment commonseg;
if (seg_a.end<seg_b.start || seg_a.start>seg_b.end)
{
commonseg.start = 0;
commonseg.end = 0;
}
else {
commonseg.start = max(seg_a.start, seg_b.start);
commonseg.end = min(seg_a.end, seg_b.end);
}
return commonseg.end - commonseg.start;
}
int findLongestSegment(const vector<segment>&segments, int size)
{
vector<int>lens(size );
lens[0] = 0;
lens[1] = commonSegment(segments[0], segments[1]);
int tmplen;
for (int i = 2; i <size; i++)
{
lens[i] = lens[i - 1];
for (int j = 0; j < i - 1; j++)
{
tmplen = commonSegment(segments[i], segments[j]);
lens[i] = max(lens[i], tmplen);
}
}
for (int i = 0; i < size; i++)
{
cout << lens[i] << " ";
}
cout << endl;
return lens[size - 1];
}
递归方法:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
typedef struct{
int start;
int end;
}segment;
bool isShorter(const segment &s1,const segment &s2);
segment commonSegment(const segment &seg_a,const segment &seg_b);
int findLongestSegment(const vector<segment> &segments,int size,segment &maxSegment);
int main()
{
int n;
int start,end;
while(cin>>n){
vector<segment> segments(n);
for(int i=0;i<n;i++){
if(cin>>start && cin>>end){
segments[i].start=start;
segments[i].end=end;
}
}
// sort by segment.end
//sort(segments.begin(),segments.end(),isShorter);
segment maxSeg;
int maxLen;
maxLen=findLongestSegment(segments,n,maxSeg);
cout<<"Longest Length:"<<maxLen<<endl;
cout<<"start:"<<maxSeg.start<<endl;
cout<<"end:"<<maxSeg.end<<endl;
}
return 0;
}
bool isShorter(const segment &s1,const segment &s2){
return s1.end<s2.end;
}
//assume seg_a.end<seg_b.end
segment commonSegment(const segment &seg_a,const segment &seg_b){
segment commonSeg;
if(seg_a.end<seg_b.start || seg_a.start>seg_b.end){
commonSeg.start=0;
commonSeg.end=0;
}
else{
commonSeg.start=max(seg_a.start,seg_b.start);
commonSeg.end=min(seg_a.end,seg_b.end);
}
return commonSeg;
}
int findLongestSegment(const vector<segment> &segments,int size,segment &maxSegment){
if(size<=1)
return 0;
if(size==2){
maxSegment=commonSegment(segments[0],segments[1]);
return maxSegment.end-maxSegment.start;
}
// size>2
// recursive method
int maxLen,tmpLen;
segment tmpMaxSeg;
maxLen=findLongestSegment(segments,size-1,tmpMaxSeg);
maxSegment=tmpMaxSeg;
// maxSegment=(maxSegment,commonSeg)
segment commonSeg;
for(int i=0;i<size-1;i++){
commonSeg=commonSegment(segments[i],segments[size-1]);
tmpLen=commonSeg.end-commonSeg.start;
if(tmpLen>maxLen){
maxLen=tmpLen;
maxSegment=commonSeg;
}
}
return maxSegment.end-maxSegment.start;
}
转载:https://www.cnblogs.com/AndyJee/p/4537376.html