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