ZOJ Problem Set - 1076
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=76
这个比较简单,一次就AC了,简单说下贪婪策略。
1 首先按照Exon的结束点非降序排序;
2 遍历有序列,若当前结点与前一个结点有重叠,则删除当前结点。
用反证法能够很容易证明该贪婪策略能贪出最优结果。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct Exon {
int BGN;
int END;
int NO;
};
bool NMT1(const Exon& A, const Exon& B) {
if(A.END < B.END) {
return true;
} else if(A.END == B.END) {
return A.BGN <= B.BGN;
} else {
return false;
}
}
bool NMT2(const Exon& A, const Exon& B) {
return A.END <= B.END;
}
int main()
{
int dataSize, loop, rightEdge;
vector<Exon> DNA;
vector<Exon>::iterator It;
Exon tmp;
while(1) {
cin >> dataSize;
if(!dataSize) break;
DNA.clear();
for(loop = 1; loop <= dataSize; loop++) {
cin >> tmp.BGN >> tmp.END;
tmp.NO = loop;
DNA.push_back(tmp);
}
sort(DNA.begin(), DNA.end(), NMT2);
It = DNA.begin();
rightEdge = (*It).BGN;
while(It != DNA.end()) {
if((*It).BGN >= rightEdge) {
rightEdge = (*It).END;
It++;
} else {
It = DNA.erase(It);
}
}
It = DNA.begin();
cout << (*It).NO;
for(; It < DNA.end(); It++) {
if(It == DNA.begin()) continue;
cout << " " << (*It).NO;
}
cout << endl;
}
return 0;
}