專案安排 離散化 DP

2021-09-06 11:14:44 字數 2269 閱讀 9144

題目描述:

小明每天都在開源社群上做專案,假設每天他都有很多專案可以選,其中每個專案都有乙個開始時間和截止時間,假設做完每個專案後,拿到報酬都是不同的。由於小明馬上就要碩士畢業了,面臨著買房、買車、給女友買各種包包的鴨梨,但是他的錢包卻空空如也,他需要足夠的money來充實錢包。萬能的網友麻煩你來幫幫小明,如何在最短時間內安排自己手中的專案才能保證賺錢最多(注意:做專案的時候,專案不能並行,即兩個專案之間不能有時間重疊,但是乙個專案剛結束,就可以立即做另乙個專案,即專案起止時間點可以重疊)。

輸入:

輸入可能包含多個測試樣例。

對於每個測試案例,輸入的第一行是乙個整數n(1<=n<=10000):代表小明手中的專案個數。

接下來共有n行,每行有3個整數st、ed、val,分別表示專案的開始、截至時間和專案的報酬,相鄰兩數之間用空格隔開。

st、ed、value取值均在32位有符號整數(int)的範圍內,輸入資料保證所有資料的value總和也在int範圍內。

輸出:

對應每個測試案例,輸出小明可以獲得的最大報酬。

樣例輸入:

3

1 3 6

4 8 9

2 5 16

41 14 10

5 20 15

15 20 8

18 22 12

樣例輸出:

16

22思路:

這題初看和01揹包問題類似,不同的是這裡的開始和截止時間沒有明確的上限,所以直接用01揹包問題來做肯定是有問題的。這道題給出的上限就是專案的個數最大為10000,我們可以從這個分析,表示時間的狀態最多有20000種。所以我們必須對每個專案的開始和截止時間進行離散化到0~20000之間,這樣就把問題轉化到01揹包了。

定義dp[x],表示截止到時間x,小明可以獲得的最大報酬。狀態轉移方程為:

dp[x] = max (l為專案的截止時間為x的開始時間)

對於離散化,可以對專案中出現的開始和截止時間存入set容器進行排序,排序後的各時間在容器中的下標就是它們的離散化值,用這些離散化值來更高對於的專案開始和截止時間就完成了對時間的離散化。

具體**如下:

1 #include 2 #include 

3 #include 4

using

namespace

std;

56 typedef struct

_task_t

7task_t;

1011

set index_map; //

用於下標的離散化

12 map index_map_map; //

存放離散化的結果

13 task_t task_data[10005]; //

存放輸入資料

14 multimap task_map; //

用於任務的對映

15int dp[20005]; //

用於dp

16int n; //

任務的個數

17int max_proj; //

任務的最大時間

1819

#define max(a, b) (a >= b ? a : b)

20int main(void)21

38 i = 0;39

set::iterator iterator_index =index_map.begin();

40for (; iterator_index != index_map.end(); iterator_index++)

41 index_map_map.insert(map::value_type(*iterator_index, i++));

42 max_proj =i;

43for (i = 1; i <= n; i ++)

4449 dp[0] = 0;50

for (i = 1; i < max_proj; i ++)

5159

}60 cout << dp[max_proj - 1] <

62return0;

63 }

view code

總結:第一次在a題的時候用c++的stl庫,表示很強大!!!!

vijos p1002 過河(離散化dp)

過河 在河上有一座獨木橋,乙隻青蛙想沿著獨木橋從河的一側跳到另一側。在橋上有一些石子,青蛙很討厭踩在這些石子上。由於橋的長度和青蛙一次跳過的距離都是正整數,我們可以把獨木橋上青蛙可能到達的點看成數軸上的一串整點 0,1,l 其中l是橋的長度 座標為0的點表示橋的起點,座標為l的點表示橋的終點。青蛙從...

hdu 5009 離散化 鍊錶 dp

這道題因為顏色給的資料範圍大於資料總數,所以要對顏色進行離散化後再進行操作 而這道題每次更新,可以用鍊錶記錄當前情況下每種顏色最靠近當前位置的所在位置後,因為最終花費是c c,所以每乙個所選區間的顏色數不能大於sqrt 區間長度 所以可以得到n sqrt n 複雜度演算法的動態規劃如下 dp i m...

HDU 3607 線段樹 離散化 DP

n個連續的盒子,每個盒子有高度h和價值v,選擇任意一點進入,且從任意一點出來,進入後只能從左向右走,且每次走到的盒子高度必須更高,可以跳過低的盒子 狀態轉移方程 dp i max dp j v i 0 jh j 用線段樹優化,尋找 j include stdio.h include string.h...