基礎貪心題選講

#171. 智力大沖浪

題目描述

小偉報名參加中央電視臺的智力大沖浪節目。本次挑戰賽吸引了衆多參賽者,主持人爲了表彰大家的勇氣,先獎勵每個參賽者m元。先不要太高興!因爲這些錢還不一定都是你的?!接下來主持人宣佈了比賽規則:首先,比賽時間分爲n個時段(n≤500),它又給出了很多小遊戲,每個小遊戲都必須在規定期限ti時時間段之前完成(1≤ti≤n)。
如果一個遊戲沒能在規定期限前完成,則要從獎勵費m元中扣去一部分錢wi,wi爲自然數,不同的遊戲扣去的錢是不一樣的。當然,每個遊戲本身都很簡單,保證每個參賽者都能在一個時間段(要佔一個單位時間)內完成,而且都必須從整時段開始。
主持人只是想考考每個參賽者如何安排組織自己做遊戲的順序。作爲參賽者,小偉很想贏得冠軍,當然更想贏取最多的錢!
注意:比賽絕對不會讓參賽者賠錢!

輸入格式

第1行爲m,表示一開始獎勵給每位參賽者的錢;第2行爲n,表示有n個小遊戲;第3行有n個數,分別表示遊戲1到n的規定完成期限;第4行有n個數,分別表示遊戲1到n不能在規定期限前完成的扣款數。

輸出格式

僅1行。表示小偉能贏取最多的錢。

樣例數據

input

10000
7
4 2 4 3 1 4 6
70 60 50 40 30 20 10

output

9950

...首先,可以先將每個小遊戲按扣錢數爲關鍵字從大到小排序。對規定期限離散化(勉強這麼叫吧),開一個vis數組。O(n)掃一遍,如果1-i的時間都已經被佔用,則扣掉當前遊戲的錢,由於已經排過序,當前遊戲的扣錢數肯定比前面的扣錢數少。

	sort(a+1,a+n+1,mycmp);
	for(i=1;i<=n;i++)
	{
	    k=a[i].time;
	    while(c[k]&&k>0)k--;
	    if(k>0)c[k]=1;
	        else m-=a[i].money;
	}

#172. 紀念品分組

題目描述

元旦快到了,校學生會讓樂樂負責新年晚會的紀念品發放工作。爲使得參加晚會的同學所獲得的紀念品價值相對均衡,他要把購來的紀念品根據價格進行分組,但每組最多隻能包括兩件紀念品, 並且每組紀念品的價格之和不能超過一個給定的整數。爲了保證在儘量短的時間內發完所有紀念品,樂樂希望分組的數目最少。

你的任務是寫一個程序,找出所有分組方案中分組數最少的一種,輸出最少的分組數目。

【限制】

50%的數據滿足: 1 <=n <= 15

100%的數據滿足: 1 <= n <= 30000, 80 <= W <= 200

輸入格式

第1行包括一個整數w,爲每組紀念品價格之和的上眼= 第2行爲一個整數n,表示購來的紀念品的總件數G

第3-n+2行每行包含一個正整數Pi (5 <= Pi <= w3)w表示所對應紀念品的價格。

輸出格式

僅1行,包含一個整數, ep最少的分組數目合

樣例數據

input

100
9
90
20
20
30
50
60
70
80
90

output

6

數據規模與約定

時間限制:1s

空間限制:256MB

以紀念品的價格爲關鍵字從小到大排序

設兩個指針ij,分別從頭和尾掃

如果a[i] + a[j]滿足題目的要求,則選擇,i++ j--

如果不滿足,則是過大,使j--,a[j]就會變小(已從小到大排序),繼續試探是否滿足要求

(我個菜B偷懶寫了個O(n ^ 2),事實上只需要O(n))

(代碼可能跟解釋不一樣,因爲是O(n ^ 2)的代碼(我菜),大概意思還是差不多的)

         sort(a+1,a+n+1);
	 for (i=1;i<=n;i++)
	  for (j=n;j>i;j--)
	   {
	   	if ((a[i]+a[j]<=mmax)&&(b[i])&&(b[j]))
	   	 {
	   	 	b[i]=false;
	   	 	b[j]=false;
	   	 	max++;
	   	 }
	   }

#174. 修理牛棚

題目描述

在一個暴風雨的夜晚,農民約翰的牛棚的屋頂、門被吹飛了。 好在許多牛正在度假,所以牛棚沒有住滿。 有些牛棚裏有牛,有些沒有。 所有的牛棚有相同的寬度。 自頂遺失以後,農民約翰必須儘快在牛棚之上豎立起新的木板。 他的新木材供應者將會供應他任何他想要的長度,但是供應者只能提供有限數目的木板。 農民約翰想將他購買的木板總長度減到最少。 給出 M(1<= M<=50),可能買到的木板最大的數目;S(1<= S<=200),牛棚的總數;C(1 <= C <=S) 牛棚裏牛的數目,和牛所在的牛棚的編號stall_number(1 <= stall_number <= S),計算攔住所有有牛的牛棚所需木板的最小總長度。 輸出所需木板的最小總長度作爲的答案。

輸入格式

第 1 行: M , S 和 C(用空格分開) 第 2 到 C+1行: 每行包含一個整數,表示牛所佔的牛棚的編號。

輸出格式

單獨的一行包含一個整數表示所需木板的最小總長度。

樣例數據

input

4 50 18
3
4
6
8
14
15
16
17
21
25
26
27
30
31
40
41
42
43

output

25

數據規模與約定

時間限制:1s1s

空間限制:256MB256MB

註釋

[ 一種最優的安排是用板攔住牛棚3-8,14-21,25-31,40-43.]

通過觀察題面和樣例,我們可以知道:要達到最優解,必須讓可以不覆蓋的範圍最大

則可以先對c個牛棚以編號爲關鍵字從小到大排序,然後求出每兩個牛棚的差

存在一個數據結構(可以存在可持久化線段樹裏,取出1-m-1大)(還可以存在斐波那契裏堆食用風味更佳)  (你要存在暴力實現可持久化的splay也沒問題),然後取出最大的m - 1個數

然後就可以亂搞了

inline void init()
{
	if (m > c)
	 {
	 	printf("%d\n", c);
	 	exit( 0 );
	 }
	for (int i = 1 ; i <= c; i++)
	 a[i] = read();
	sort(a + 1 , a + c + 1);
	for (int i = 2; i <= c ; i++)
	 {
	 	long long c = (long long) ( a[i] ) - a[i - 1] - 1;
		b[++t] = c;
	 }
}

inline void work()
{
	sort(b + 1, b + t + 1);
	long long ans1 = 0;
	ans = a[c] - a[1] + 1;
	for (int i = c - 1 ;i > c - m;i--)
	 ans1 += b[i];
	printf("%lld\n", ans - ans1);
}

256M1

首先安裝

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章