ACM筆記之貪心

2021-10-25 00:22:45 字數 3754 閱讀 6898

用點最多能覆蓋多少個區間,乙個點最多只能覆蓋乙個區間

q:給定n個區間和m個點,乙個點最多只能使用一次,詢問最多有多少個區間可以被點覆蓋到?

a:首先按照區間左端點從小到大排序點也按照從小到大排序,反向列舉每個區間,在此基礎上再反向列舉點,如果這個點在區間中,那麼答案加1,統計完就是最終答案。演算法時間複雜度為 o(n

2)

o(n^2)

o(n2

)優化:利用upper_bound o(l

ogn)

o(logn)

o(logn

)得到第乙個大於區間右端點的點,再自減(要加哨兵)就是第乙個小於等於區間右端點的點,如果這個點同時又滿足大於區間左端點,就讓答案加1,演算法時間複雜度為 o(n

long

n)

o(nlongn)

o(nlon

gn)

例如:acwing 110

#include

using

namespace std;

const

int n =

2505

;typedef pair<

int,

int> pii;

pii cow[n]

;//區間(第一關鍵字為左端點,第二為右端點),點(點的值,點的數目)

int n,m;

intmain()

sort

(cow, cow + n)

;for

(int i =

0,x, y; i < m;

++ i)

int cnt =0;

mp[0]

= mp[

1001

]= n;

for(

int i = n -

1; i >=0;

-- i)

} cout << cnt << endl;

}

q:給定兩組點設為組a,b,每組點都有兩個引數x和y,一組中的某個點 a(屬於a) 只能和另一組的某個點 b(屬於b) 匹配(當且僅當 a 的兩個引數都大於 b),若匹配成功b會得到一定的回報,不能重複匹配,詢問最大的匹配數?在此基礎上詢問最大的權值

a:一般最大帶邊權匹配問題用km演算法(要求是完全匹配),最大帶點權問題用匈牙利演算法。而此題可以利用引數的性質貪心,將兩個引數以x為第一關鍵字,y為第二關鍵字從大到小排序,然後從前往後列舉能獲得回報的那組點(組b),利用mutiset維護符合x上匹配條件的組a中的點,每次選擇大於等於yb的那個點就是最優演算法。

acwing127

#include

using

namespace std;

const

int n =

1e5+5;

struct machine

}a[n]

;struct task

}b[n]

;int n,m;

intmain()

for(

int i =

0; i < m;

++ i)

sort

(a,a+n)

;sort

(b,b+m)

; multiset<

int>set;

int cnt =0;

long

long sum =0;

for(

int i =

0, j =

0; i < m;

++ i)

} cout << cnt <<

" "<< sum << endl;

}return0;

}

q:給定n個區間,詢問最少可以合併成多少個區間,兩個區間能合併當且僅當區間沒有交集(包括端點)。

a:貪心,演算法的時間複雜度為o(n

logn

)o(nlogn)

o(nlog

n)1.按區間左端點排序

2.用小根堆維護當前區間最後乙個區間的右端點,即最小的右端點

3.從前往後列舉區間,如果當前區間的左端點小於最小的右端點,說明要新加乙個區間,否則直接更新最小右端點即可。

acwing 111

/*

類似區間合併

*/#include

using

namespace std;

const

int n =

5e4+5;

typedef pair<

int,

int> pii;

typedef pairint> piii;

int n;

piii a[n]

;int id[n]

;struct node};

intmain()

sort

(a+1

,a+1

+n);

///按照區間左端點排序

int ans =0;

priority_queueq;

///過載小根堆

for(

int i=

1;i<=n;

++i));

id[a[i]

.second]

= ans;

}else);

id[a[i]

.second]

= idx;}}

cout << ans << endl;

for(

int i=

1;i<=n;

++i) cout << id[i]

<< endl;

}

最少用多少個點能覆蓋全部區間,乙個點可以同時覆蓋多個區間

思路:1.先求每個點能被探測到的雷達放置區間

2.按照右端點從小到大排序

3.從前往後列舉每個區間,如果當前區間包含最後乙個點則繼續,否則選取當前區間的右端點作為新的點

#include

using

namespace std;

const

int n =

1005

;typedef pair<

double

,double

> pdd;

typedef pair<

int,

int> pii;

int n,d;

pii p[n]

;pdd a[n]

;int x,y;

intmain()

double t =

sqrt

(d*d - y*y)

; a[i]

.first = x+t, a[i]

.second = x-t;

}double k =

-dbl_max;

int ans =0;

sort

(a+1

,a+1

+n);

for(

int i=

1;i<=n;

++i)

} cout << ans << endl;

}

ACM演算法之貪心演算法

acm演算法之貪心演算法 一般使用貪心演算法要滿足兩個條件 a.貪心選擇性質 可通過做區域性最優 貪心 選擇來達到全域性最優解。貪心選擇性質 這是貪心演算法與動態規劃的區別 b.最優子結構性質 問題的最優解包含了子問題的最優解。貪心演算法的基本思想 找出整體當中每個小的區域性的最優解,並且將所有的這...

ACM 貪心演算法

這是大學期間acm校賽時我出的一道題,考貪心演算法,沒有牽涉複雜的資料結構,有題目加源 贏取最多最有價值的禮物 problem description 五一期間到長沙烈士公園玩,走進去之後,發現許多人在圍在一起玩一種遊戲,遊戲規則是 給你m個環,用乙個環可以套住乙個禮物,同時丟擲時要花費一秒鐘的時間...

ACM 貪心演算法

acm 貪心演算法 在求最優解問題的過程中,依據某種貪心標準,從問題的初始狀態出發,直接去求每一步的最優解,通過若干次的貪心選擇,最終得出整個問題的最優解,這種求解方法就是貪心演算法。從貪心演算法的定義可以看出,貪心演算法不是從整體上考慮問題,它所做出的選擇只是在某種意義上的區域性最優解,而由問題自...