標籤:動態規劃、最短路
題目大意:
有k個任務分布在第1至n這n個時間點,第i個任務的於第 \(p_i\) 分鐘開始,持續時間為 \(t_i\) 分鐘,則該任務將在第 \(p_i+t_i-1\) 分鐘結束。
如果時刻i你是空閒的,而此時有至少乙個任務是在時刻i開始的,那麼你必須要在其中選擇乙個任務來做;
如果時刻i你是空閒的,而沒有任何乙個任務是在時刻i開始的,那麼你在時刻i就可以是空閒的。
求你最多有多少個時刻是空閒的。
我們令 \(f[i]\) 表示從時刻i開始到時刻n結束的這段時間範圍內的最大空閒時刻數量。
那麼我們就可以從n到1遍歷時刻i,對於時刻i:
實現**如下:
#include using namespace std;
const int maxn = 10010;
int n, k, p, t, f[maxn];
vectorg[maxn];
int main()
for (int i = n; i >= 0; i --)
}cout << f[1] << endl;
return 0;
}
這個思路來自 tong_xz大佬的部落格
將時間點作為圖中的點。
從第p分鐘開始,持續時間為t分鐘的任務視為從p點到p+t點連一條權為t的邊。(邊的起點是任務的起始時間,終點是任務結束時間的下一分鐘)
如果乙個點到最後也沒有出度,則向後乙個點連邊權為0的邊(沒活幹,這一分鐘他可以摸魚。。。)
跑最短路就得到他至少要幹多長時間,答案就是(n-最短路結果)
如果將邊權作為休息時間的話用最長路也能做。
實現**如下:
#include using namespace std;
const int maxn = 10010;
int in[maxn], out[maxn], n, k, p, t, dis[maxn];
bool vis[maxn];
vector< pair> g[maxn];
queueque;
void spfa() }}
}}int main()
for (int i = 1; i <= n; i ++)
spfa();
cout << n - dis[n+1] << endl;
return 0;
}
洛谷P1280 尼克的任務
一道比較另類的dp,一開始沒想出來,覺得應該不用dp搞就能出來,然後看了題解發現原來這麼簡單。dp i 表示從i開始的最大空閒時間,逆序推dp,分情況 1 如果改時間沒有工作需要開始,那麼當然是要休息的,表示現在休息一分鐘,dp i dp i 1 1 2 如果有需要開始的,那麼在所有需要開始的工作中...
洛谷 P1280 尼克的任務
題目描述 尼克每天上班之前都連線上英特網,接收他的上司發來的郵件,這些郵件包含了尼克主管的部門當天要完成的全部任務,每個任務由乙個開始時刻與乙個持續時間構成。尼克的乙個工作日為n分鐘,從第一分鐘開始到第n分鐘結束。當尼克到達單位後他就開始幹活。如果在同一時刻有多個任務需要完戍,尼克可以任選其中的乙個...
洛谷P1280 尼克的任務
題目描述 尼克每天上班之前都連線上英特網,接收他的上司發來的郵件,這些郵件包含了尼克主管的部門當天要完成的全部任務,每個任務由乙個開始時刻與乙個持續時間構成。尼克的乙個工作日為n分鐘,從第一分鐘開始到第n分鐘結束。當尼克到達單位後他就開始幹活。如果在同一時刻有多個任務需要完戍,尼克可以任選其中的乙個...