用Dij的思想優化DP

2022-01-10 17:00:45 字數 1947 閱讀 4954

如果 \(dp\) 的狀態轉移方程為 \(f[i]=min\\)

那麼我們就可以考慮用 \(dij\) 的思想去優化它

因為如果某個點的 \(f\) 值是最小的,那麼就沒有其它的點可以影響它

因此我們每一次從堆中取出最小的點對其它點進行更新即可

題目描述

傳送門分析

按照期望題一般的做法,我們設 \(f[u]\) 為從 \(u\) 走到終點 \(n\) 的期望花費

設 \(du[u]\) 為節點 \(u\) 的出度

那麼 \(f[u]= \frac min(f[u],f[v])}+1\)

我們會發現這個式子既包含 \(f[u]\) 本身又包含與 \(f[u]\) 相鄰的點 \(f[v]\)

不好直接轉移

但是我們可以確定,如果 \(f[v],那麼 \(f[v]\) 一定會對 \(f[u]\) 做出貢獻

因此,我們可以利用 \(dij\) 的思想開乙個小根堆,每次取出最小的來更新其它的

因為當前的值是最小的,所以一定不會有其它的點可以影響它

我們設 \(u\) 被與它相鄰的點的 \(f\) 值更新了 \(cnt\) 次,這些值的和為 \(sum\)

則 \(f[u]=\frac+1\)

整理可得 \(f[u]=\frac\)

**

#include#include#includeconst int maxn=6e5+5;

inline int read()

while(ch>='0' && ch<='9')

return x*fh;

}int head[maxn],tot=1;

struct asdb[maxn];

void ad(int aa,int bb)

struct jie

jie(int aa,double bb)

bool operator < (const jie &a) const

};int n,m,du[maxn],cnt[maxn];

double sum[maxn],f[maxn];

bool vis[maxn];

std::priority_queueq;

void dij() }}

int main()

dij();

printf("%.10f\n",f[1]);

return 0;

}

題目描述

傳送門分析

我們設消滅第 \(i\) 個頭的代價是 \(f[i]\)

則,\(f[i]=min(f[i],a[i]+\sum f[j],b[i])\)

同樣地,我們在一開始把所有的 \(f\) 值扔進小根堆裡

每次取出隊首的元素來更新其它值

**

#include#include#include#include#include#includeconst int maxn=6e5+5;

typedef long long ll;

int head[maxn],tot=1;

struct asdb[maxn];

int n;

void ad(int aa,int bb)

struct jie

jie(int aa,ll bb)

bool operator < (const jie &a) const

};ll a[maxn],f[maxn];

int k[maxn];

bool vis[maxn];

std::priority_queueq;

void dij()

} }}int main()

} dij();

long long ans=0;

for(int i=1;i<=n;i++)

printf("%lld\n",ans);

return 0;

}

DIJ的優化,和spfa的優化

spfa和dij求最短路的演算法的坑點一直是很多的。經常會讓人搞不懂。用過載運算子來排序,如 struct cmp 這種做法是不對的,該dis值在堆裡不會更新甚至會堵住。目前只有兩種優化演算法最可靠,分別為優先佇列來優化spfa或dij。每次從堆中只需要取出到t的最短路最小的元素進行鬆弛,這樣便可以...

區間DP的主要思想

區間動態規劃問題一般都是考慮,對於每段區間,他們的最優值都是由幾段更小區間的最優值得到,是分治思想的一種應用,將乙個區間問題不斷劃分為更小的區間直至乙個元素組成的區間,列舉他們的組合 求合併後的最優值。設f i,j 1 i j n 表示區間 i,j 內的數字相加的最小代價 最小區間f i,i 0 乙...

hdu1579簡單的用dp優化遞迴

題目連線 include include include include include include const int inf 0x3f3f3f using namespace std int dp 110 n,a 110 110 sum 110 maxx int main for int i...