HDU5630 Hiking(貪心+優先佇列)
題目連結:傳送門
題意:
邀請n個人去參加聚會,對於第i個人只有當去人數大於等於li,小於等於ri的時候這個人才會去參加聚會,
讓你確定一個邀請的順序,使得最後去參加聚會的人數最多。
分析:
讀完題目後就感覺這個題是個貪心,但是沒有想好怎麼去維護,比賽完了看完題解感覺太水了。。。
首先肯定是要按照l對所有的數進行排序,比如說我們當前已經有tot個人確定參加了,那麼剩下的我們
還要貪心的進行選擇。選擇滿足l<=tot&&r>=tot中的r最小的那個人,很明顯,只有這樣選擇對後來人的
影響才是最小的。對整體才是最優的。
用優先佇列維護的程式碼:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <queue>
#include <set>
#include <vector>
using namespace std;
const int maxn = 1e5+10;
struct nod{
int l,r,id;
bool operator < (const struct nod & tmp)const{
return r > tmp.r;
}
}p[maxn];
int ans[maxn];
bool vis[maxn];
bool cmp(const struct nod &p1,const struct nod &p2){
if(p1.l==p2.l) return p1.r<p2.r;
return p1.l<p2.l;
}
int main()
{
int t,n;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&p[i].l);
p[i].id=i;
}
for(int i=1;i<=n;i++){
scanf("%d",&p[i].r);
}
sort(p+1,p+n+1,cmp);
int tot=0,i=1,id=0;
priority_queue<nod>Q;
while(1){
while(p[i].l<=tot&&i<=n) Q.push(p[i]),i++;
while(!Q.empty()){
nod tmp = Q.top();
if(tmp.r>=tot) break;
ans[++id]=tmp.id;
Q.pop();
}
if(Q.empty()) break;
else{
ans[++id] = Q.top().id;
tot++;
Q.pop();
}
}
while(i<=n) ans[i]=p[i].id,i++;
printf("%d\n",tot);
for(int i=1;i<n;i++) printf("%d ",ans[i]);
printf("%d\n",ans[n]);
}
return 0;
}
用set維護的程式碼:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <queue>
#include <set>
using namespace std;
const int maxn = 1e5+10;
struct nod {
int l ,r ,id ;
bool operator < (const struct nod &tmp) const {
if(l == tmp.l)
return r < tmp.r ;
return l<tmp.l ;
}
} p[maxn];
int ans[maxn];
bool vis[maxn];
set<pair<int,int > >st;
set<pair<int,int > >::iterator it;
int main() {
int t,n;
scanf("%d",&t);
memset(vis,0,sizeof(vis));
while(t--) {
scanf("%d",&n);
for(int i=1; i<=n; i++) {
scanf("%d",&p[i].l);
p[i].id=i;
}
for(int i=1; i<=n; i++) {
scanf("%d",&p[i].r);
}
sort(p+1,p+1+n);
//memset(vis,0,sizeof(vis));
int tot=0,i=1;
st.clear();
while(true) {
while(tot>=p[i].l&&i<=n) st.insert(make_pair(p[i].r,p[i].id)),i++;
if(st.size()==0) break;
while(st.size()) {
it = st.begin();
if(it->first >= tot) break;
st.erase(st.begin());
}
if(st.size()) {
it = st.begin();
ans[++tot] = it->second;
vis[it->second]=1;
st.erase(st.begin());
}
}
printf("%d\n",tot);
for(int i=1; i<=n; i++) {
if(!vis[i]) ans[++tot]=i;
else vis[i]=0;
}
for(int i=1; i<n; i++)
printf("%d ",ans[i]);
printf("%d\n",ans[n]);
}
return 0;
}
相關文章
- 8.13(優先佇列貪心維護+打表找規律+對頂堆優先佇列+DFS減枝+貪心dp)佇列
- Sunscreen POJ - 3614(防曬油) 貪心-優先佇列佇列
- CodeForces - 960B:Minimize the error(優先佇列+貪心)Error佇列
- uva10954Add All(貪心+優先佇列)佇列
- [USACO 2009 Feb Gold] Fair Shuttle (貪心+優先佇列)GoAI佇列
- BZOJ 1572 [Usaco2009 Open]工作安排Job:貪心 + 優先佇列【先放再更新】佇列
- hdu5380 貪心+雙端佇列佇列
- Codeforces Round #390 (Div. 2)(A,B,C(記憶化搜尋),D(貪心,優先佇列))佇列
- PHP優先佇列PHP佇列
- 堆--優先佇列佇列
- 優先佇列 (轉)佇列
- BZOJ 1724 [Usaco2006 Nov]Fence Repair 切割木板:貪心 優先佇列【合併果子】AI佇列
- 淺談優先佇列佇列
- STL 優先佇列 用法佇列
- 堆與優先佇列佇列
- 堆和優先佇列佇列
- 優先佇列和堆排序佇列排序
- 堆排序與優先佇列排序佇列
- Java優先佇列(PriorityQueue)示例Java佇列
- BZOJ1029: [JSOI2007]建築搶修[模擬 貪心 優先佇列]JS佇列
- 01揹包優先佇列優化佇列優化
- 棧,佇列,優先順序佇列簡單介面使用佇列
- Redis實現任務佇列、優先順序佇列Redis佇列
- NO GAME NO LIFE(優先佇列/最小堆)GAM佇列
- 優先佇列的比較器佇列
- 封裝優先順序佇列封裝佇列
- 二叉堆優先佇列佇列
- POJ 3253 Fence Repair 優先佇列AI佇列
- 堆——神奇的優先佇列(上)佇列
- 優先佇列的效能測試佇列
- hdu5040 優先佇列+bfs佇列
- 佇列 優先順序佇列 python 程式碼實現佇列Python
- 演算法面試(三) 優先佇列演算法面試佇列
- STL優先佇列最小堆最大堆佇列
- STL醜數(set+優先佇列)佇列
- 【圖論】拓撲排序+優先佇列圖論排序佇列
- 1007(優先佇列)佇列
- POJ 1724 ROADS(優先佇列+spfa)佇列