(翻譯來自洛谷)
題目描述
John的農場在給奶牛擠奶前有很多雜務要完成,每一項雜務都需要一定的時間來完成它。比如:他們要將奶牛集合起來,將他們趕進牛棚,爲奶牛清洗乳房以及一些其它工作。儘早將所有雜務完成是必要的,因爲這樣纔有更多時間擠出更多的牛奶。當然,有些雜務必須在另一些雜務完成的情況下才能進行。比如:只有將奶牛趕進牛棚才能開始爲它清洗乳房,還有在未給奶牛清洗乳房之前不能擠奶。我們把這些工作稱爲完成本項工作的準備工作。至少有一項雜務不要求有準備工作,這個可以最早着手完成的工作,標記爲雜務1。John有需要完成的n個雜務的清單,並且這份清單是有一定順序的,雜務k(k>1)的準備工作只可能在雜務1..k-1中。
寫一個程序從1到n讀入每個雜務的工作說明。計算出所有雜務都被完成的最短時間。當然互相沒有關係的雜務可以同時工作,並且,你可以假定John的農場有足夠多的工人來同時完成任意多項任務。
輸入輸出格式
輸入格式:
第1行:一個整數n,必須完成的雜務的數目(3<=n<=10,000);
第2 ~ n+1行: 共有n行,每行有一些用1個空格隔開的整數,分別表示:
工作序號(1..n,在輸入文件中是有序的);
完成工作所需要的時間len(1<=len<=100);
一些必須完成的準備工作,總數不超過100個,由一個數字0結束。有些雜務沒有需要準備的工作只描述一個單獨的0,整個輸入文件中不會出現多餘的空格。
輸出格式:
一個整數,表示完成所有雜務所需的最短時間。
輸入輸出樣例
輸入樣例#1:
7
1 5 0
2 2 1 0
3 3 2 0
4 6 1 0
5 1 2 4 0
6 8 2 4 0
7 4 3 5 6 0輸出樣例#1:
23
看似是一道很難的數據結構的題目,實際上可以用遞推來做……
完成每一件事所需要的總時間就是這件事的準備工作中最晚完成的時間加上完成這件事所需要的時間,即t[i]=t[ max(ready[i]) ]+len[i]
,最後找到最大的 t[i] 就可以了。
#include <bits/stdc++.h>
using namespace std;
struct thing{
int id; //見題目
int len; //見題目
int th[110]; //所需要的準備工作
}st[51000];
int ans,t[51000];
int main()
{
int n,tot=1;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
int j,t,x;
scanf("%d%d%d",&st[i].id,&st[i].len,&st[i].th[tot]);
while(st[i].th[tot]!=0)
scanf("%d",&st[i].th[++tot]);
tot=1;
}
//以下爲核心代碼
for(int i=1;i<=n;i++)
{
if(st[i].th[1]==0)
t[i]=st[i].len;
else break;
}
for(int i=1;i<=n;i++)
{
if(!t[i])
{
int j=0;
while(st[i].th[++j]!=0)
t[i]=max(t[i],t[st[i].th[j]]+st[i].len);
}
}
//以上爲核心代碼
for(int i=1;i<=n;i++)
ans=max(ans,t[i]);
cout<<ans;
return 0;
}
祝dalao們省選快樂……(逃)