~~萌新在這裡記錄一下 ~~
a.不重疊的線段 51nod - 1133
最基礎的區間問題~也就是《挑戰》一書中p41貪心提到的區間問題(選取最多的工作數目)
tips:題意就不說了8~ 貪心的思想,工作結束的越早(線段的右端點越小),越對後面的影響小。
要注意端點可不可以重合,每個題要求不一樣~
#include
using
namespace std;
struct nodebook[
10005];
intcmp
(node n1, node n2)
int n,cnt,last;
void
solve()
printf
("%d"
, cnt);}
intmain()
下面給出另一種(麻煩一點的)做法,主要是為了b做鋪墊~
思路也是貪心,左端點排序後右端點排序,然後用tmp記錄,每次都排序,tmp[1]儲存右端點最大的,tmp[2]儲存當前的,然後判斷,如果不相交,繼續;如果相交,把tmp[1](右端點打,對後續影響大的點)刪掉,tmp[1]更改為tmp[2]。
正確性分析:由於是從左到右掃瞄,當前兩個相交,去掉右端點最大的能夠最大的減少對後面區間的影響;如果不相交,因為區間左端點遞增,之後的區間肯定不會再跟這兩個裡面右端點最小的相交了,因此不用再考慮這個區間。
#include
using
namespace std;
struct nodebook[
10005
],tmp[3]
;int n,cnt;
intcmp
(node n1, node n2)
intcmp2
(node n1, node n2)
bool
intersect
(const node& n1,
const node& n2)
void
solve()
}printf
("%d"
,n - cnt);}
intmain()
b .zoj-3953-intervals【貪心】【17th浙大校賽】
tips:刪掉最少的區間,使得不存在任意三個區間兩兩相交。
思路和上面的第二種方法類似(幾乎完全一樣),左端點降序後右端點降序。然後每次取出當前右端點最長的兩個線段和當前線段比較,若不相交繼續;相交則刪除右端點最大的線段(對後續影響最大)。正確性同樣。
#include
using
namespace std;
struct nodebook[
50005
], tmp[4]
;int n,ans[
50005
],cnt,t;
intcmp1
(node n1, node n2)
intcmp2
(node n1, node n2)
bool
intersect
(node &n1, node& n2)
void
solve()
sort
(book +
1, book +
1+ n, cmp1)
; tmp[1]
= book[1]
, tmp[2]
= book[2]
;for
(int i =
3; i <= n;
++i)
}printf
("%d\n"
,cnt)
;sort
(ans +
1, ans +
1+ cnt)
;for
(int i =
1; i <= cnt;
++i)
printf
("%d "
,ans[i]);
putchar
('\n');
}int
main()
return0;
}
區間問題 區間選點 區間問題 貪心
玄學的貪心問題,一般全憑直覺。貪心問題沒有固定討論,沒有模板,見多了就好了,證明想法的正確性是很困難的,大多採用反證法。905.區間選點 貪心思路 證明 時間複雜度 o n logn o nlogn o nlog n include include using namespace std const...
貪心區間問題
1 選擇不相交問題 51nod1133 數軸上有n個開區間 ai,bi 盡量選擇多個區間,是的這些區間兩兩之間沒有共同點。include include include include define ll long long define maxn 100005 int n using namesp...
貪心 區間問題
區間選點 定n個閉區間 ai,bi ai,bi 請你在數軸上選擇盡量少的點,使得每個區間內至少包含乙個選出的點。輸出選擇的點的最小數量。位於區間端點上的點也算作區間內。輸入格式 第一行包含整數n,表示區間數。接下來n行,每行包含兩個整數ai,bi ai,bi 表示乙個區間的兩個端點。輸出格式 輸出乙...