題目大意:
0為牆1為路2為起點3為終點4為炸彈
走到任意乙個炸彈都可以將所有炸彈重置倒計時6minutes
每走乙個位置需要1minutes
問從2到3需要的最少時間
dfs法更快。
bfs法好理解。
思路:兩種方法都需理解一點:
同乙個炸彈位置當第二次走到時說明已不是最優解。
bfs法:
處理走到同乙個炸彈位置方法:第一次走到炸彈的位置時,將該炸彈設定為0(即牆),將不會再一次走到此處。
然後就是bfs了。
dfs法:
記憶化搜尋。
記錄走過該點的時間與炸彈剩餘**時間。
剪枝:去掉同樣走到該位置時所用時間更久和剩餘**時間更短的路。
由於bfs法在遍歷過程中遍歷了更多沒必要的路,所以更慢些。
bfs**
#include#include#include#define n 10
using namespace std;
int map[n][n],n,m;
int dir[4][2]=
, /*向右*/
, /*向左*/
, /*向下*/
/*向上*/
};struct node
start;
void bfs()
else if(map[q2.x][q2.y]==4)
q.push(q2);//將這一步放進佇列 }}
} //佇列掃完都沒搜到答案,說明答案不存在
printf("-1\n");
return;
}int main()
,,,};
int map[10][10];
int step[10][10];
int time[10][10];
int ans;
int n,m,sx,sy;
void dfs(int x,int y,int nowstep,int bombtime)
if(map[x][y]==4)
bombtime=6;
//最優剪枝
//下面的這個剪枝很重要,不剪就會超時
//從當前點x,y走到下乙個可能點的距離大於從其他途徑到nx,ny的距離,且到nx,ny點時的剩餘時間大於由x,y點到nx,ny點後的剩餘時間,就跳過
//這是因為結點可重複訪問所以本身沒標記,那麼當上述條件滿足時,由nx,ny開始的最優解已經求過(存在或者不存在),所以不需要再重複求了。
if(nowstep>=step[x][y]&&time[x][y]>=bombtime)
return ;
step[x][y]=nowstep;
time[x][y]=bombtime;
int nx,ny;
for(int i=0;i<4;i++)
}int main()
} ans=0x3f3f3f3f;
dfs(sx,sy,0,6);
if(ans==0x3f3f3f3f)
printf("-1\n");
else
printf("%d\n",ans);
} return 0;
}
hdu1072 逃離迷宮系列 bfs
題意 逃離迷宮,路中可能有炸彈,總時間是6個單位,在有炸彈的位置,如果到達的時刻時間大於0,則恢復到6時間,炸彈的位置可以重複到達,求出最終至少需要多少步才能走出迷宮,到達終點。這樣的最優化問題和地圖相關的,bfs應該足以解決。我們考慮到乙個位置可能被多次訪問,所以狀態引數應該設定乙個時間,設定為訪...
HDU1501 Zipper(DFS 記憶化搜尋)
題意 給三個字串,保證第三個串長度是前兩個串長度之和,確定前兩個串保持原有的字母順序能不能拼成第三個串。思路 直接搜尋的話會有大量重複的運算,要用記憶化陣列記錄之前的結果。當匹配到第乙個串的第i位和第二個串的第j位時,前面可能有多種情況,但三個串後面的長度一定,所以結果也可以確定,用vis i j ...
Hdu 1428(記憶化搜素 最短路)
hdu 1428 思路 求出圖的逆向最短路,即每個點到 n,n 的最短路,然後求出 1,1 到 n,n 的最短路的數量,num i j 記錄點 1,1 到 i,j 過程中的最短路的條數,然後遇到之前求過最短路的點就直接返回,否則求解後再返回。參考文章 include include include ...