mysql動態規劃 動態規劃

2021-10-19 15:35:09 字數 3637 閱讀 2194

動態規劃

能夠動態規劃的問題具有以下特點:

可分解成規模更小的子問題

子問題的結果可復用

關鍵是要理解狀態轉移方程的含義就好啦!

數字三角形

問題描述

在數字三角形尋找從頂到底的路徑,使得路徑經過的數字之和最大。規定每一步只能往左下或右下走,求出最大路徑和。

遞迴解法

#include

#include

using namespace std;

constexpr int n = 100;

int num********[n][n];

int n; //數字三角形高度

int maxpath( int i, int j) while (x < n);

分析開闢另外乙個二維陣列,自底向上記錄最大路徑。其實若不要求輸出具體路徑,可以將dp覆蓋在原數字三角形陣列中以求節約空間。覆蓋方式可以是每次迴圈都覆蓋在最後一行。

0-1揹包

問題描述

選擇物品的組合,以期在有限的空間裡裝下最大價值。

example

假定揹包最大容量是10,且每種物品的重量,價值如下

weight

value

填表過程

填表的過程是自上而下,從左到右,每一步都是當前情況下的最優解。

capacity = int(capacity) #總容量

kind = int(kind) #總種類

weight = np.zeros(kind + 1,dtype = int)

value = np.zeros(kind + 1,dtype = int)

for i in range(1,kind+1):

weight[i],value[i] = input().strip().split()

dp = np.zeros((kind+1,capacity+1),dtype = int) #記錄動態規劃過程的**

for i in range(1,kind+1):

for j in range(1,capacity+1):

if(operator.lt(j,weight[i])): #在當前容量下,若裝不下,不裝

dp[i][j] = dp[i-1][j]

else:

dp[i][j] = max(dp[i-1][j],dp[i-1][j-weight[i]]+value[i]) #在當前容量下,若裝得下,取裝與不裝的最大值

print(dp[kind][capacity])

分析可是使用一維陣列來作空間優化,帶來的缺點是無法回溯具體是選擇那幾樣物品。通過觀察狀態轉移方程可以得知,dp[i][j]只與dp[i-1][j],dp[i-1][j-w(i)]有關,能夠下一行覆蓋上一行。但是在內迴圈中,若是依舊從左往右,計算dp[i-1][j-w(i)]時這個值已經被更新導致失效,所以內迴圈需要逆序掃瞄。

#include

#include

using std::cin;

using std::cout;

using std::endl;

int dp[100];

int value[100], weight[100];

int main()

int m, n;

cin >> m >> n;

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

cin >> weight[i] >> value[i];

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

for (int j = m - 1; j >= weight[i]; --j)

dp[j] = std::max(dp[j], dp[j - weight[i]] + value[i]);

cout << dp[m - 1] << endl;

最長公共子串行

問題描述

longest common subsequence,從給定的兩個序列中取得盡可能多的字元,要求按原序列的先後次序得到。(不要求連續)

狀態轉移方程

若i == 0或者 j == 0,則x或y其一是空串,最大公共序列是0

若x[i] == y[j],那麼在這個位置上的最優解 = 子串x[i-1]與子串y[j-1]的最長公共子串行 + 1

若x[i] != y[j],則選擇子串x[i-1]和子串y[i]的最長公共子串行與子串x[i]和子串y[j-1]的最長公共子串行的較大者

#include

#include

#include

using namespace std;

int main() while (i >= 0 && j >= 0);

for (unsigned int i = 0; i < y.length(); ++i) //二維陣列的釋放

deletedp[i];

delete dp;

2020/8/16更

最長公共子串

最長公共子串與最長公共子串行的不同在於要求子串必須是連續的,那麼狀態轉移方程就簡化了許多,判斷每乙個位置字元相同的時候前一位是否也相同,填表的時候儲存長度最大值。

#include

#include

#include

using namespace std;

int main() {

string x, y ;

int maxlen = 0;

cin >> x >> y;

int** dp = new int* [x.length() + 1];

for (unsigned int i = 0; i <= x.length(); ++i)

dp[i] = new int[y.length() + 1];

for (unsigned int i = 0; i <= x.length(); ++i)

for (unsigned int j = 0; j <= y.length(); ++j) {

if (i == 0 || j == 0|| x[i] != y[j]) //初始化邊界條件

dp[i][j] = 0;

else

dp[i][j] = dp[i - 1][j - 1] + 1;

maxlen = max(maxlen, dp[i][j]);

cout << maxlen << endl;

for (unsigned int i = 0; i < y.length(); ++i) //二維陣列的釋放

deletedp[i];

delete dp;

vijos1476 旅遊規劃 動態規劃

傳送門 題解 我是這麼做的,首先第一遍求出每個點向下的不相交的最長鏈和次長鏈,這樣兩條鏈拼起來就是就是過這個點 不包含他的父親的情況下 的最長鏈。在這些最長鏈中取max就可以得到直徑。然後乙個點在直徑上,要麼他本身就在已經求出的最長鏈上 就是從這個點出發的最長 次長鏈 直徑長度 要麼如果這個點在某一...

矩陣連乘 動態規劃 動態規劃解矩陣連乘問題

一.矩陣鏈事例 矩陣鏈問題主要涉及的時在多個矩陣相乘,如何通過相乘的順序來減少程式執行。二.例題分析 這次分析過程按照動態規劃的三個基本條件來逐步解答 1 尋找最優子結構 假設我們已經找到父矩陣鏈最優解,當我們劃分到最後一步時都是兩個子矩陣鏈 分別被括號包圍 相乘,如 a1a2a3a4 a5a6a7...

NOIP 搜尋與動態規劃 動態規劃重難點習題詳解

1.動態規劃習題講解 例題2 6 過河 noip2005 問題描述 在河上有一座獨木橋,乙隻青蛙想沿著獨木橋從河的一側跳到另一側。在橋上有一些石子,青蛙很討厭踩在這些石子上。由於橋的長度和青蛙一次跳過的距離都是正整數,我們可以把獨木橋上青蛙可能到達的點看成數軸上的一串整點 0,1,l 其中l是橋的長...