最開始,筆者將狀態 fif_
fi 定義為1到i的最小花費 ,我們不難得到這樣的乙個狀態轉移方程,即
f i=
(sum
ti−s
umtj
+s+c
ostj
)∗(s
umfi
−sum
fj
)f_=(sumt_-sumt_+s+cost_)*(sumf_-sumf_)
fi=(s
umti
−su
mtj
+s+c
ostj
)∗(
sumf
i−s
umfj
)。可是我們發現這時 cos
tj
cost_
costj
非常不好算,而且當前的決策還會對後面的決策產生影響,而且這個轉移方程是明顯不具備最優子結構的(想一想, 為什麼?)。
那麼,我們就換乙個思路,將 fif_
fi 重新定義,我們可將 fif_
fi 定義為
f i=
min(
fj+(
sumf
i−su
mfj)
∗(su
mti−
sumt
j+s)
+(su
mti−
sumt
j+s)
∗(su
mfn−
sumf
i)
)f_=min(f_+(sumf_-sumf_)*(sumt_-sumt_+s)+(sumt_-sumt_+s)*(sumf_-sumf_))
fi=mi
n(fj
+(s
umfi
−su
mfj
)∗(s
umti
−su
mtj
+s)+
(sum
ti−
sumt
j+s
)∗(s
umfn
−su
mfi
))即我們定義的 fif_
fi 還考慮了對後面的貢獻,這樣就可以愉快的進行dp了。
時間複雜度是 o(n
2)
o(n^2)
o(n2
) ,其實我們還可以用斜率優化將其優化到 o(n
)o(n)
o(n)
,不過方法不難,筆者就不再闡述。
code:
#include
#include
using namespace std;
const
int maxn =
5002
;const
long
long inf =
10000000000+3
;long
long sumf[maxn]
, sumt[maxn]
, f[maxn]
;int
main()
for(
int i =
1;i <= n;
++i)
printf
("%lld"
,f[n]);
return0;
}
P2365 任務安排
n個任務排成乙個序列在一台機器上等待完成 順序不得改變 這 n個任務被分成若干批,每批包含相鄰的若干任務。從零時刻開始,這些任務被分批加工,第 i個任務單獨完成所需的時間為 ti 在每批任務開始前,機器需要啟動時間 s,而完成這批任務所需的時間是各個任務需要時間的總和 同一批任務將在同一時刻完成 每...
動態規劃 洛谷P2365 任務安排
n個任務排成乙個序列在一台機器上等待完成 順序不得改變 這n個任務被分成若干批,每批包含相鄰的若干任務。從時刻0開始,這些任務被分批加工,第i個任務單獨完成所需的時間是ti。在每批任務開始前,機器需要啟動時間s,而完成這批任務所需的時間是各個任務需要時間的總和 同一批任務將在同一時刻完成 每個任務的...
P2365 任務安排 題解
p2365 任務安排 這道題有弱化版和強化版,這道題是弱化版 我們很容易能想到乙個 dp 方程 f p i 表示前 i 個取了 p 段的最優解,於是轉移方程 f p i min f p 1 j st i p ast s ast sf i sf j 這個轉移方程是 o n 3 的考慮怎麼優化 對於每次...