之前學習過一段時間的動態規劃,但掌握的不夠牢固,實際做題時還是不能靈活的運用,所以打算在寒假對這部分知識進行學習和鞏固,按照洛谷的提單分為五個部分進行學習:
1.動態規劃的引入
2.線性狀態動態規劃
3.區間與環形動態規劃
4.樹與圖上的動態規劃
5.狀態壓縮動態規劃
本文題目選自第一部分的練習內容
題目:過河卒
題目內容:棋盤上 aa 點有乙個過河卒,需要走到目標 bb 點。卒行走的規則:可以向下、或者向右。同時在棋盤上 cc 點有乙個對方的馬,該馬所在的點和所有跳躍一步可達的點稱為對方馬的控制點。因此稱之為「馬攔過河卒」。棋盤用座標表示,aa 點 (0, 0)(0,0)、bb 點 (n, m)(n,m),同樣馬的位置座標是需要給出的。現在要求你計算出卒從 aa 點能夠到達 bb 點的路徑的條數,假設馬的位置是固定不動的,並不是卒走一步馬走一步。
樣例: 輸入:6 6 3 3 輸出: 6
解題過程:這道題很明顯要用動態規劃的思想來做,直接算出有多少條路是不現實的,所以拆分成算每一格有多少條路,並把馬的控制點做為動態規劃的條件:
1.當上一步和左一步都是馬的控制點時,到這一步的路數為: 0+0 = 0
2.當僅有上一步是馬的控制點時,到這一步的路數為: 0 + 左一步的路數 = 左一步的路數
3.當僅有左一步是馬的控制點時,到這一步的路數為: 上一步的路數 + 0 = 上一步的路數
3.當上一步和左一步都不是馬的控制點時,到這一步的路數為: 上一步的路數+左一步的路數
**為:
if
(area[i-1]
[j]==-1
&& area[i]
[j-1]==
-1) area[i]
[j]=0;
else
if(area[i-1]
[j]==-1
) area[i]
[j]= area[i]
[j-1];
else
if(area[i]
[j-1]==
-1) area[i]
[j]= area[i-1]
[j];
else area[i]
[j]= area[i]
[j-1
]+ area[i-1]
[j];
注意判斷邊界,即馬的控制點會不會超出棋盤範圍:
if
(hx-
2>=
0&& hy-
1>=0)
area[hx-2]
[hy-1]
=-1;
if(hx-
1>=
0&& hy-
2>=0)
area[hx-1]
[hy-2]
=-1;
if(hx+
1<= bx && hy-
2<= by)
area[hx+1]
[hy-2]
=-1;
if(hx+
2<= bx && hy-
1>=0)
area[hx+2]
[hy-1]
=-1;
最後還要注意路數會超出int範圍,所以dp陣列要用long long int儲存(因為這個細節第一次提交wa的兩個樣例):
long
long
int area[25]
[25];
全部**:
#include
using
namespace std;
long
long
int area[25]
[25];
int bx,by,hx,hy;
void
init()
for(
int j=
0;j<=bx;j++)}
voiddp(
)}}int
main()
心得:
通過今天的練習,我複習了之前練習的動態規劃的題目,學習了動態規劃的思想,即把乙個無法直接得到答案的複雜問題分成若干個較簡單的小問題,通過對小問題進行求解並彙總最終得到大問題的答案,這一思想不僅在程式設計中很厲害,在現實生活中對我也有所啟發。
動態規劃的引入2
繼續昨天的練習,今天又做了題單裡的一些題,選了一道比較有意思的題作為本文內容。題目 挖地雷 題目內容 在乙個地圖上有nn個地窖 n le 20 n 20 每個地窖中埋有一定數量的地雷。同時,給出地窖之間的連線路徑。當地窖及其連線的資料給出之後,某人可以從任一處開始挖地雷,然後可以沿著指出的連線往下挖...
動態規劃1
維基百科 動態規劃是一種在數學和 電腦科學 中使用的,用於求解包含 重疊子問題 的最優化 問題的方法。其基本思想是,將原問題分解為相似的子問題,在求解的過程中通過子問題的解求出原問題的解。動態規劃的思想是多種演算法的基礎,被廣泛應用於電腦科學和工程領域。比較著名的應用例項有 求解 最短路徑 問題,揹...
動態規劃 1
動態規劃是對最優化問題的一種新的演算法設計方法。由於各種問題的性質不同,確定最優解的條件也互不相同,因而動態規劃的沒計法對不同的問題,有各具特色的表示方式。不存在一種萬能的動態規劃演算法。但是可以通過對若干有代表性的問題的動態規劃演算法進行討論,學會這一設計方法。多階段決策過程最優化問題 動態規劃的...