遊戲通關
xy在玩乙個包含n
'>n
個任務的遊戲。每個任務完成時限為t
i'>ti
(你可以認為還沒開始做任務時的時間為0
'>0
),獎勵為w
i'>wi
。由於xy技術的嫻熟以及任務的簡單,對於每個任務,他都可以在乙個單位時間內完成。
xy想要知道他能夠獲得的最多的獎勵。
第一行乙個整數n
'>
n,表示需要完成的任務數目。
接下來n
'>
n行,每行兩個整數t、w
'>t、w
,分別表示完成這個任務的最後期限和完成這個任務後獲得的獎勵。
輸出資料有且僅有一行,只包含乙個整數,表示最多獲得的獎勵。
21 51 4
5
【樣例輸入2】
52 31 2
4 51 3
3 4
【樣例輸出2】
15
【樣例解釋2】
對於樣例2,xy可以選擇完成任務1、3
、4'>1、3、4
和5'>
5,這樣他可以獲得獎勵15
'>
15。【資料規模及約定】
對於10%的資料,n
≤100,t
i≤100,wi
≤2000
'>n≤100,ti≤100,wi≤2000
。對於30%的資料,n
≤1000,t
i≤5000,w
i≤2000
'>n≤1000,ti≤5000,wi≤2000
。對於50%的資料,n
≤10000,t
i≤20000,w
i≤2000
'>n≤10000,ti≤20000,wi≤2000
。對於100%的資料,n
≤200000,t
i≤200000,w
i≤2000
'>n≤200000,ti≤200000,wi≤2000
。思路:
這道題解法即為貪心+大根堆,首先我們觀察,對於從第二晚結束的任務的結束的時間t2+1開始到結束時間最大的任務的結束時間t1結束,這段時間內只能做最晚結束的任務;對於從第三晚的任務的結束時間t3+1開始,到第二晚的任務的結束時間內,只能做第二晚或者最晚的任務········,因此以此類推對於某一時刻,值可以做結束時間大於此時刻的任務,於是就有一種貪心策略,即每次選取可行的任務中的利益最大的任務。我們開始將資料存在結構體中,並對結構體按照時間從大到小排序。然後我們倒敘列舉時刻,用大根堆維護,使用乙個變數tot記錄已經加入過堆中元素的個數,每列舉到乙個時刻,掃瞄tot至n,如果此任務的結束時間大於或等於我們列舉到的時刻就將其加入堆中,注意:我們列舉的時刻是結束時間因而從所有任務的結束時刻的最大值列舉到最晚的結束時刻1。
**:
1 #include2 #include3 #include4 #include5 #include6 #include7using
namespace
std;
8#define maxn 200010
9#define m(x,y) make_pair(x,y)
10#define clear(a) memset(a,0,sizeof a)
1112
intn,tim,tot,ans;
13struct
edgee[maxn];
16 priority_queueq;
1718
bool
cmp(edge a,edge b)
1922
23int
main()
2433 sort(e+1,e+n+1
,cmp);
34for(int i=tim;i>=1;i--)
3542
}43 cout<"\n"
;44return0;
45 }
一本通 高手訓練 撲克牌
一副撲克牌有n n張牌。一般你買的一副新撲克牌裡除了這n n張牌外還會有一些張特殊的牌,如果你不小心弄丟了n n張牌中的某一張,就可以用特殊牌來代替,但是如果你弄丟兩張的話就沒有辦法了,因為特殊牌上的圖案是一樣的。現在你得到了很多撲克牌,準確來說,n n n種牌你各有a1,a2,an a1,a2,a...
一本通 高手訓練 1781 死亡之樹 狀態壓縮dp
link 死亡之樹 關於去重 還是有講究的。題目求本質不同的 具有k個葉子節點的樹的個數 不能上矩陣樹。點數很少容易想到裝壓dp 考慮如何刻畫樹的形狀 發現乙個維度做不了 所以。設狀態 f i j 表示 點的集合為i葉子集合的點為j的方案樹。這樣我們就能知道這棵樹大致的樣子 空間 為 2 當然 如果...
佇列(一本通)
這道題重點是關係的轉換和初始化 include include include includeusing namespace std int a 101 記錄接著的的那個節點 int n,m int main int ans void bfs int x,int y int main cout in...