線性DP 尼克的任務

2021-07-15 11:47:12 字數 2546 閱讀 9288

尼克每天上班之前都連線上英特網,接收他的上司發來的郵件,這些郵件包含了尼克主管的部門當天要完成的全部任務,每個任務由乙個開始時刻與乙個持續時間構成。 尼克的乙個工作日為n分鐘,從第一分鐘開始到第n分鐘結束。當尼克到達單位後他就開始幹活。如果在同一時刻有多個任務需要完成,尼克可以任選其中的乙個來做,而其餘的則由他的同事完成,反之如果只有乙個任務,則該任務必需由尼克去完成,假如某些任務開始時刻尼克正在工作,則這些任務也由尼克的同事完成。如果某任務於第p分鐘開始,持續時間為t分鐘,則該任務將在第p+t-1分鐘結束。 寫乙個程式計算尼克應該如何選取任務,才能獲得最大的空暇時間。

輸入資料第一行包含兩個用空格隔開的整數n和k,1≤n≤10000,1≤k≤10000,n表示尼克的工作時間,單位為分,k表示任務總數。 接下來共有k行,每一行有兩個用空格隔開的整數p和t,表示該任務從第p分鐘開始,持續時間為t分鐘,其中1≤p≤n,1≤p+t-1≤n。

輸出檔案僅一行包含乙個整數表示尼克可能獲得的最大空暇時間。

15 6

1 21 6

4 11

8 58 1

11 54

思路:首先,我必須珍而重之的說,這個題是倒推的,倒推比較簡單,因為正推有後效性

一維的線性動歸,狀態轉移方程:e[j].from != i   f[i] = f[i+1] + 1

e[j].from = i    f[i] = max

所設變數:

int n, k;//n為尼克的工作時間(min),k為任務總數

node e[n];//原始資料

//成員from是工作起始點,to是工作時間,也就是說 第from+to-1分鐘 當前任務結束,第from+to分鐘 就可以開始新工作了

int f[n];//記錄 i 時間到n所能得到的最大空閒時間

根據第一題樣例,我們可以得到兩個**

e[n]

fromto1

1221

63411

4855

81611

5 f[n]陣列i1 

234 5

678 9

1011 

1213

1415

f[i]43

2165

4321

0432

1 先來解釋一下狀態轉移方程:

①e[j].from != i   f[i] = f[i+1] + 1

我們要求最大的空閒時間,所以我們倒著推,i 是從 n 開始的(實際上會用到f[n+1],由於其值為0不等於所以不用特意初始化),當第 j 個任務上邊界不等於當前時間,說明 i 時間所能得到的最大空閒時間比 i+1 時間所能得到的最大空閒時間多一分鐘,就是 f[i] = f[i+1] + 1;

看f[n]陣列的**也可以看出來這點,都是以1為單位遞增或遞減的

②e[j].from = i    f[i] = max

e[j].from + e[j].to 指的是可以開始新工作的時間點,由題目中的(p+t-1)可知,e[j].from + e[j].to 就是第 j 個任務結束的時間點

以樣例為例:

紫色塊就是滿足 e[j].from = i 的 i;

i = 11時,e[6].from = i, f[11] = max = max  =max = 0;

i = 8時,e[5].from = i, f[8] = max = max = max = 2;

i = 8時,e[4].from = i, f[8] = max = max = max = 3;

i = 4時,e[3].from = i, f[4] = max = max  =max = 1;

i = 1時,e[2].from = i, f[1] = max = max  =max = 4;

i = 1時,e[6].from = i, f[1] = max = max  =max = 4;

推而廣之,可得 f[i] = max

**:

#include #include #include #include #include #include using namespace std;

//f[i]表示從時間i起的最大空閒時間,逆推

const int n = 10000 + 10;

int n, k;

int f[n];

struct nodee[n];

int cmp(node a, node b)

void dp()}}

}int main()

/*15 6

1 21 6

4 11

8 58 1

11 5

---------

4*/

反思:我一開始是把f[n]設為0到 i 時間最少的工作時間,也就是正推,做了很久沒做出來,因為有後效性,所以要考慮的比較多;

但是我並不覺得正推就不可能實現,我有一定的思路,今晚嘗試後再給出答案;

那麼這就有個問題,如果有後效性,那這個問題就應該換乙個角度看,還是有後效性就是複雜些但還是可以做出來的

尼克的任務 線性dp

p1280 尼克的任務 洛谷 電腦科學教育新生態 luogu.com.cn 一道線性dp的基礎題。但是狀態方程自己想複雜了。剛開始是想用二維陣列表示,選擇i項工作後時間到j的總工作時長最小是多少,然後用總時間減它。很麻煩,而且不會寫.然後看了題解,發現只需要一維陣列即可。狀態表示是從第i分起開始工作...

尼克的任務DP

尼克每天上班之前都連線上英特網,接收他的上司發來的郵件,這些郵件包含了尼克主管的部門當天要完成的全部任務,每個任務由乙個開始時刻與乙個持續時間構成。尼克的乙個工作日為n分鐘,從第一分鐘開始到第n分鐘結束。當尼克到達單位後他就開始幹活。如果在同一時刻有多個任務需要完戍,尼克可以任選其中的乙個來做,而其...

luogu1280 尼克的任務 (線性dp)

題目描述 尼克每天上班之前都連線上英特網,接受他的上司發來的郵件,這些郵件包含了尼克主管的部門當天要完成的全部任務,每個任務由乙個開始時刻與乙個持續時間構成。尼克的乙個工作日為n分鐘,從第一分鐘開始到第n分鐘結束。當尼克到達單位後他就開始幹活。如果在同一時刻有多個任務需要完成,尼克可以任選其中的乙個...