原題傳送門
0.前言
顯然,這是一道動態規劃(\(dp\))的入門題,也是一道非常經典的例題。
1.思路
\(dp\)和貪心主要就不同在:\(dp\)求全域性最優解,貪心求區域性最優解
這道題顯然不是用貪心來做,因為當前的區域性最優解可以不是全域性最優解
\(solution\ 1\) . 逆推
首先輸入乙個三角形樣的三角形
for(int i=1;i<=r;i++)
}
因為是逆推,所以我們要先定義好\(dp\)陣列裡的最後一行的狀態
for(int i=1;i<=r;i++)
然後是最關鍵的一步,求出如下的狀態轉移方程:\(dp[i][j]=a[i][j]+max(dp[i+1][j],dp[i+1][j+1]);\)
\(dp[i][j]\)表示當前位置到最後一行的經過所有數的總和
\(max(dp[i+1][j],dp[i+1][j+1]);\) 指向左右兩個方向取較大值
這裡用加號的原因是逆推
放兩張圖來理解一下
輸入的\(a\)陣列
最後的\(dp\)陣列
\(solution\ 2\) . 順推
逆推完了當然也可以順推。思路大致與上無異。
依然輸入乙個三角形樣的三角形
for(int i=1;i<=r;i++)
}
然後對三角形頂端的位置進行初始化
dp[1][1]=a[1][1];
接著還是這個關鍵的狀態轉移方程:\(dp[i][j]=a[i][j]+max(dp[i-1][j],dp[i-1][j-1]);\)
思路和上面一樣,只不過是順推,要往來時路上面進行取最大值
不過有一點不一樣:順推推出來的結果最大值不確定,所以還需要找出結果:
int res=0;
for(int i=1;i<=r;i++)
}
再放兩張圖
輸入的\(a\)陣列
最後的\(dp\)陣列
2.**
//逆推
#include#includeusing namespace std;
inline void read(int &x)
while(ch>='0'&&ch<='9')
x*=f;
}int r;
int a[1001][1001];
int dp[1001][1001];
int main()
} for(int i=1;i<=r;i++)
for(int i=r;i>=1;i--)
} printf("%d",dp[1][1]);
return 0;
}
//順推
#include#includeusing namespace std;
inline void read(int &x)
while(ch>='0'&&ch<='9')
x*=f;
}int r;
int a[1001][1001];
int dp[1001][1001];
int main()
} dp[1][1]=a[1][1];
for(int i=1;i<=r;i++)
} int res=0;
for(int i=1;i<=r;i++)
} printf("%d",res);
return 0;
}
1258 例9 2 數字金字塔
原題鏈結 觀察下面的數字金字塔。寫乙個程式查詢從最高點到底部任意處結束的路徑,使路徑經過數字的和最大。每一步可以從當前點走到左下方的點也可以到達右下方的點。在上面的樣例中,從13 13 13到8 8 8到26 26 26到15 15 15到24 24 24的路徑產生了最大的和86 86 86。第乙個...
動態規劃2 例9 2數字金字塔
例9.2數字金字塔 觀察下面的數字金字塔。寫乙個程式查詢從最高點到底部任意處結束的路徑,使路徑經過數字的和最大。每一步可以從當前點走到左下方的點也可以到右下方的點方法一 從最高點按照規則走到最低點的路徑的最大的權值和,路徑起點終點固定,走法規則明確,可以考慮用搜尋演算法 定義遞迴函式 void df...
數字金字塔 一維,順推)
題目 description 你和權權是一對很好很好的朋友。有一天,你們無聊得很,便上網衝浪,突然在乙個叫做usaco的網中找到了乙個遊戲 數字金子塔 遊戲規則是這樣的 求乙個數字金字塔中從最高點開始在底部任意處結束的路徑經過數字的和的最大,其中的每一步可以走到下方的點也可以到達右下方的點。例如在下...