雙向搜尋 DP 拯救公主(二)

2021-07-07 05:16:48 字數 1534 閱讀 4252

時間限制: 1 sec  

記憶體限制: 128 mb

[ 提交][

狀態][

討論版]

公主被妖怪抓到了乙個山洞裡,為了盡快營救公主,王子決定不回城搬救兵去獨自營救。山洞為矩形且十分空曠,其中生活著k個妖怪。幸運的是這些妖怪晚上都會睡覺並且沒人守夜。但是若是離妖怪太近就會驚醒它,其他的妖怪也會被驚醒,所以我們要找一條距離所有妖怪都很遠的路。我們把山洞分為了n*m個格仔,走到相鄰的格仔(不含對角)王子需要一步,妖怪只佔乙個格仔的大小。王子希望你給他一條盡可能安全的路,你只需要告訴他,這條路上離妖怪最近的時候距離是多少(最少走k步可到則認為最近距離為k)。入口在1行1列,公主在n行m列。

n,m,k(地圖為n行*m列,k為妖怪個數)(1

離妖怪最近的距離

3 3 2
1 3
3 1
1

k值變大

最近距離的演算法為行數差加列數差(即從入口到公主的最短距離為(n-1)+(m-1))。

該題中:妖怪數目變大

程式的優化是:在計算最近距離時,先計算每行的離妖怪距離最近的值,更新過地圖陣列 map 後,再每列用 dp 思想,一次從上到下地更新地圖的值,再一次從下向上更新,繼而取得每個點上距離每個妖怪的最近距離

源程式為:

#include#include#include#include#includeusing namespace std;

#define min(x,y) (x=1 && i<=n && j>=1 && j<=m && map[i][j]) return true;

else return false;

}int bfs(int xx,int yy)

if(vis[now2.x][now2.y])

for(int i=0;i<4;i++)

tmp2.x=now2.x+c[i][0];

tmp2.y=now2.y+c[i][1];

tmp2.v=min(map[tmp2.x][tmp2.y],now2.v);

if(check(tmp2.x,tmp2.y) && !vis2[tmp2.x][tmp2.y])

} }if(dd==1)

else if(dd==2)

else return 0;

}int main()

for(int i=1;i<=m;i++){

ax[1][i]=map[1][i];

for(int j=2;j<=n;j++){

if(ax[j-1][i]+1=1;d--){

if(by[d+1][i]+1

測試資料:

1000 1000 10

732 474

449 988

119 239

306 233

258 268

627 992

225 792

237 601

72 361

1 951

執行結果為:232

雙向廣度搜尋 拯救公主(一)

時間限制 1 sec 記憶體限制 128 mb 提交 狀態 討論版 公主被妖怪抓到了乙個山洞裡,為了盡快營救公主,王子決定不回城搬救兵去獨自營救。山洞為矩形且十分空曠,其中生活著k個妖怪。幸運的是這些妖怪晚上都會睡覺並且沒人守夜。但是若是離妖怪太近就會驚醒它,其他的妖怪也會被驚醒,所以我們要找一條距...

二叉搜尋樹與雙向列表

題目描述 輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成乙個排序的雙向鍊錶。要求不能建立任何新的結點,只能調整樹中結點指標的指向。題目分析 對於本題其實考察的是對於樹的遍歷,對於二叉搜尋樹,其性質之一是樹的根節點大於左子樹的節點而小於右子樹的節點,而題目想要我們將一顆二叉搜尋樹轉換成乙個有序的的雙向鍊錶。...

二叉搜尋樹 區間DP

有 n 個結點,第 i 個結點的權值為 i 你需要對它們進行一些操作並維護一些資訊,因此,你需要對它們建立一棵二叉搜尋樹。在整個操作過程中,第 i 個點需要被操作 x i 次,每次你需要從根結點一路走到第 i 個點,耗時為經過的結點數。最小化你的總耗時。第一行乙個整數n,第二行n個整數x1 xn。輸...