題意 :尼克每天上班之前都連線上英特網,接收他的上司發來的郵件,這些郵件包含了尼克主管的部門當天要完成的全部任務,每個任務由乙個開始時刻與乙個持續時間構成。尼克的乙個工作日為n分鐘,從第一分鐘開始到第n分鐘結束。當尼克到達單位後他就開始幹活。如果在同一時刻有多個任務需要完成,尼克可以任選其中的乙個來做,而其餘的則由他的同事完成,反之如果只有乙個任務,則該任務必需由尼克去完成,假如某些任務開始時刻尼克正在工作,則這些任務也由尼克的同事完成。如果某任務於第p分鐘開始,持續時間為t分鐘,則該任務將在第p+t-1分鐘結束。寫乙個程式計算尼克應該如何選取任務,才能獲得最大的空暇時間。
分析 :
根據題意,不妨試試定義 dp[i] = 1~i 這個時間段尼克最大空閒時間
但是會發現乙個問題,如果是這樣定義的話,那麼如果當前點 i 是
有任務的話那麼,肯定是從 dp[i + t] 這個狀態轉移到 dp[i] 的。
具體的含義就是,選擇做 i 這個工作,顯然在 i 這個工作的工作時間
段內是沒有空閒時間的,那麼 i 點的空閒時間就要從做完 i 之後的
時間點中選擇最優的進行轉移。所以嘚從後往前 dp ,當然這個是
取決於 dp 狀態的定義,洛谷題解上有從前向後的 dp,可以去看一下
那麼改變一下定義有 dp[i] = i~n 這個時間段尼克的最大空閒時間
那麼對於每乙個點,有兩種情況
① i 這個點是某一任務的開頭 dp[i] = max( dp[i], dp[i+t] )
② i 這個點沒有任務 dp[i] = dp[i+1] + 1、表示當前空閒時間相比上乙個點 + 1
那麼這樣子,對於每乙個有任務的點,往後跳 t 個時間點的狀態轉移
就能做到如果選擇了這個任務,那麼將失去多少時間,得到多少時間的空閒
#includeusingview codenamespace
std;
const
int maxn = 1e4 + 10
;struct
assign;
}arr[maxn];
intdp[maxn];
bool
flag[maxn];
intn, k;
int main(void
) }
}return !printf("
%d\n
", dp[1
]);}
洛谷,P1280 尼克的任務 線性dp
尼克每天上班之前都連線上英特網,接收他的上司發來的郵件,這些郵件包含了尼克主管的部門當天要完成的全部任務,每個任務由乙個開始時刻與乙個持續時間構成。尼克的乙個工作日為n分鐘,從第一分鐘開始到第n分鐘結束。當尼克到達單位後他就開始幹活。如果在同一時刻有多個任務需要完成,尼克可以任選其中的乙個來做,而其...
洛谷P1280 尼克的任務(線性dp)
解 以工作開始的時間為關鍵字降序排序,從後面開始dp,若沒有任務,則當前休息時間為後面加1 dp i dp i 1 1 若有任務,則取當前dp和工作之後的dp比較取較大的,即 if dp i work num t dp i dp i dp i work num t include include i...
洛谷P1280 尼克的任務 線性DP
題意 給定工作時間n,和k個任務的起始時間p和持續時間t,從第1分鐘開始工作,某一時刻若有多個工作則任選乙個工作,若只有乙個工作則必須要選那個來做,求出能夠得到的最多的空閒時間 思路 因為時間只能是遞增的,所以可以考慮按時間倒序來做,若某一時刻沒有任務,則dp i dp i 1 1,若有任務,則dp...