出自洛谷題庫
【問題描述】不是具體題目
大概就是有n個車要過河,只有乙個橋(理論上只能單向通行,其實不用管對面),橋有最大承重,每次你可以把其中的任意一段(length<=n)輛車組成車隊,同時通過。要求總時間的最小值。
【題目分析】
一開始我在摸索的時候,感覺這道題目有種多個01揹包放在一起的感覺,因此,我開始腦補時間複雜度。。。要列舉有幾個01揹包,要列舉在**劃分揹包,然後還要多個01揹包的o(n*n)的累加。。。
然後。。。正解
首先說,這是一道區間dp,這麼說的原因是車輛的順序給定(不能超車),所以我們只能列舉區間,因此,狀態定義為二維,f[l][r],即區間左端,右端。
然後,狀態轉移方程就是在討論區間的劃分,取最小值。
初始化就是把f[i][i],第i輛車的通過時間直接求出來。
最後。。。注釋很詳細,建議複製到編譯器裡檢視。
【**+注釋】->70分
【優化方向】#include
#include
#include
//不用加
#include
#include
//不用加
#include
#include
using
namespace std;
const
int maxn=
1000
;//固定常量定義陣列上限 (水一下**行數)
double f[maxn+5]
[maxn+5]
;//dp陣列
double w[maxn+5]
[maxn+5]
,t[maxn+5]
[maxn+5]
;//存下任意區間的重量和以及通過時間( 預處理 );
struct group a[maxn+5]
;int
main()
for(
int i=
1;i<=n;i++)}
for(
int len=
2;len<=n;len++)}
//值得注意的是,區間dp不能直接列舉左右端點,因為區間dp本質是從小區間推廣到大區間,只能先從小長度來 (敲黑板)
}printf
("%.1lf\n"
,f[1
][n]*60
);return0;
}
可以考慮如下方向:
減少預處理的複雜度;
可以通過逆序迴圈來減少乙個dp陣列的維度;(如下)
簡化決策;
【優化**】->滿分
這段**是看過網上的文章後自己理解所寫,無意抄襲
全文——終double ans[maxn+5]
;//前i輛車的通過時間最小值
for(
int i=
1;i<=n;i++
) ans[i]
=1e18
;for
(int i=
1;i<=n;i++)}
}printf
("%.1lf\n"
,ans[n]*60
);
Luogu P1594護衛隊(字首和 DP)
tm搞了半天的二維dp方程還是錯的。設f i 表示前i輛車順利通過的最小時間。則對於每乙個i列舉該組車的起點j,然後從所有的f j min j i 中選乙個最小的。min j i 表示從第j輛車到第i輛車最慢的是個什麼速度。include include include include using ...
洛谷P1220 關路燈 題解 區間DP
本題涉及演算法 區間dp。我們一開始要做一些初始化操作,令 我們設狀態 f l r i 表示 則我們可以得出狀態轉移方程如下 f l r 0 min f l 1 r 0 sum l sum n sum r p l 1 p l f l 1 r 1 sum l sum n sum r p r p l f...
區間dp 洛谷P1040
這個題目是個區間dp 為什麼會在洛谷的dfs裡面,我也不知道啊 dfs啊呸,區間dp,顧名思義,就是在一段區間 l,r 上的dp 我在說什麼亂七八糟的,劃掉劃掉 乍一看這個題目,看似無從下手 可能只有我自己無從下手 其實仔細一分析,題目要,求最大值,我們就直接列舉樹根,然後把左右兒子按照題目要求的操...