タイトル:
数直線にn個の閉じた区間[a_i、b_i]があります。各インターバルに少なくとも1つのポイントが存在するように、可能な限り少ないポイントを取ります(異なるインターバルに含まれるポイントは同じでもかまいません)。
入力:
最初の行に1つの整数N(N <= 100)
行2〜N + 1、各行に2つの整数a、b(a、b <= 100)
出力:
選択したポイントの数を表す整数
例:
入力
2
1 5
4 6
出力
1
入力
3
1 3
2 5
4 6
出力
2
アイデア:
この質問の貪欲な戦略は、間隔の最後のポイントを選択することです。すべての間隔を端から小から大に並べ替え、端が同じ場合は大から小に並べ替えます。
証明:
1.間隔が含まれている場合、セルにポイントがある場合、大きな間隔にポイントがなければならないので、大きな間隔がポイントを取る必要がないように、セル内のポイントを選択することをお勧めします。間隔に状況が含まれる場合、このソート方法に従ってトラバースするときに、隣接するセルが優先的に選択されます。この場合、貪欲な戦略が正しいです。
2.区間の開始点が昇順に配置されている場合、選択区間の最後の点に明らかにより多くの区間を含めることができますが、この場合、貪欲戦略も正しいです。
コード:
#include <iostream>
#include <algorithm>
using namespace std;
struct zone
{
int be;
int end;
};
bool cmp(zone a, zone b)
{
if (a.end == b.end)
return a.be > b.be;
return a.end < b.end;
}
int main()
{
int be, end, n, count;
while (scanf("%d",&n)!=EOF)
{
count = 1;
zone *temp = new zone[n];
for (int i = 0; i < n; i++)
{
cin >> be >> end;
temp[i].be = be;
temp[i].end = end;
}
sort(temp,temp+n,cmp);
int j = 0;
for (int i = 1; i < n; i++)
{
if (temp[i].be > temp[j].end)
{
j = i;
count++;
}
}
cout << count << endl;
}
return 0;
}