動態規劃自虐行為刷題

2022-03-16 14:57:11 字數 3438 閱讀 4986

p1220 關路燈

p2279 [hnoi2003]消防局的設立

p1373 小a和uim之大逃離

p1005 矩陣取數遊戲

先說關路燈吧,幾個世紀不打區間dp都忘了;

乙個老人來回關燈,求最小消耗功率

主要思路是從起點(家)拓展區間,由小區間轉移到大區間,因為有繼續向前走還有回頭關燈兩種選擇

我們設f[i][j][k]表示區間i到j已經關完,k=0表示現在老人停在i節點上,k=1表示停在j節點上。

字首和求兩側沒有關的燈的功率;

f[i][j][0]=min(f[i+1][j][0]+(a[i+1]-a[i])*(sum[i]+sum[n]-sum[j]),f[i+1][j][1]+(a[j]-a[i])*(sum[i]+sum[n]-sum[j]));

ij關掉,由i+1,j在左在右轉移;

既然都關完停在了i節點,一定是i沒有關,而i+1到j都已經關上了;

實際上轉移過程像一滴水攤開一樣

f[i][j][1]同理

#include#include

#include

using

namespace

std;

const

int maxn=60

;int

n,c;

inta[maxn],b[maxn],sum[maxn];

int f[maxn][maxn][2

];int

main()

f[c][c][

0]=0;f[c][c][1]=0

;

for(int l=2;l<=n;l++)

}printf("%d

",min(f[1][n][1],f[1][n][0

]));

return0;

}

再來說一說消防局的設立,這道題的(題解)倒是給了乙個很好地思路(我也不會做,只能看題解了)

乙個貪心的思路,就是嗎,面對一棵樹,在一定範圍內定點能覆蓋更多的點,且答案不會更差

題的意思是找到最少的點覆蓋整個圖(不然家都燒沒了消防隊還沒到)

面對這個距離2,我們可以通過乙個點,乙個點的父親,還有他的爺爺來更新,當然要從最底層一直更新到整個樹的根節點

設disifre[i]表示距離i節點最近的消防站距離是多少,如果大於2,就在爺爺的位置安放乙個消防站,然後更新爺爺的父親和爺爺的爺爺(腦子混亂)

#include#include

#include

using

namespace

std;

const

int maxn=2010

;int

n;int

f[maxn];

intdisfire[maxn];

intdis[maxn];

intid[maxn];

bool cmp(int x,int y)

intans;

intmain()

sort(id+1,id+n+1

,cmp);

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

}printf("%d

",ans);

return0;

}

連圖都沒建,就把一道樹形dp做出來了(開心)

但是我們只有這些還不夠,我們可以拓展到距離為k

#include#include

#include

#include

#include

using

namespace

std;

const

int maxn=2010

;int

pre[maxn],last[maxn],other[maxn],l;

queue

q;stack

s;intn;

intfa[maxn];

void add(int x,int

y)int

vis[maxn];

void

bfs()

}}int

ans;

void dfs(int x,int

dis)

}void

go()

}int

main()

bfs();

go();

printf("%d

",ans);

return

0;0}

至於大逃離,我也不知道為什麼能這麼做。。。

f[i][j][p][k],位置i,j,收集魔液差為p,k=0表示小a,k=1表示uim

因為k+1變成0,所以k++;

#include#include

#include

using

namespace

std;

const

int mo=1e9+7

;const

int maxn=810

;int f[maxn][maxn][20][2

];int

n,m,k;

intans;

intg[maxn][maxn];

intmain()

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

ans+=f[i][j][0][1

]; ans%=mo;}}

printf("%d

",ans);

return0;

}

矩陣取數,每次都取每行的前乙個或最後乙個,每行互不影響,所以一行一行做就行了

因為我也不知道在**結束的,所以就打個擂台吧

#include#define ll __int128

using

namespace

std;

inline

intread()

while(ch>='

0' && ch<='

9') x=(x<<3)+(x<<1)+ch-'

0',ch=getchar();

return x*w;

}ll ans;

ll n,m;

ll a[

100][100

];ll

base[100

];ll f[

100][100

];void

print(ll x)

intmain()

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

}for(int k=1;k<=n;k++)

}ans+=sum;

}if(!ans) printf("0"

);

else

print(ans);

return0;

}

刷題 動態規劃

動態規劃法 動態規劃求解問題的四個特徵 求乙個問題的最優解 整體的問題的最優解是依賴於各個子問題的最優解 小問題之間還有相互重疊的更小的子問題 從上往下分析問題,從下往上求解問題 題目 給你一根長度為n繩子,請把繩子剪成m段 m n都是整數,n 1並且m 1 每段的繩子的長度記為k 0 k 1 k ...

動態規劃刷題總結

資料結構與演算法 41 動態規劃理論 最優子結構 無後效性和重複子問題 zj csdn部落格 乙個模型 多階段決策最優解模型,重點在於多階段,每個階段都對應著不同的狀態 三個特徵 最優子結構,無後效性,重複子問題。主要抓住最優子結構這一特徵,理解為後面的階段狀態可以由前面的階段狀態推導而來。狀態定義...

leetcode刷題 動態規劃

動態規劃 英語 dynamic programming,簡稱 dp 是一種在數學 管理科學 電腦科學 經濟學和生物資訊學中使用的,通過把原問題分解為相對簡單的子問題的方式求解複雜問題的方法。動態規劃常常適用於有重疊子問題和最優子結構性質的問題,動態規劃方法所耗時間往往遠少於樸素解法。動態規劃背後的基...