典型的動態規劃

2021-08-04 07:28:04 字數 1841 閱讀 3771

一、問題描述

給定陣列arr,arr中所有值都為整數且不重複,每個值代表一種面值的貨幣,每種面值的貨幣可以使用任意長,再給定乙個整數aim代表要找的錢數,求換錢有多少種方法

二、暴力解法

index代表的是哪種錢

i代表的是有多少張這樣的錢

對i和index分別遍歷,剩下的錢再用process1來分

最後將res返回

public static int coins1(int arr, int aim) 

return process1(arr, 0, aim);

} public static int process1(int arr, int index, int aim) else

} return res;

}

三、記憶搜尋解法

就是在暴力解法的基礎上增加乙個map

當我們要往下遍歷的時候先讀取map

看map中是否有值,有的話就不用遍歷了

減少重複遍歷的次數

public static int coins2(int arr, int aim) 

int map = new int[arr.length + 1][aim + 1];

return process2(arr, 0, aim, map);

} public static int process2(int arr, int index, int aim, int map) else else

}} map[index][aim] = res == 0 ? -1 : res;

return res;

}

四、動態規劃解法

也是建立乙個矩陣用來儲存,不過這裡不像記憶搜尋一樣用到的時候亂搜了

而是有順序的進行,首先需要人為地將第一行和第一列弄滿

然後根據規則進行矩陣中每個元素的填充

其中的k指的是arr[index]型別錢的張數

public static int coins3(int arr, int aim) 

int dp = new int[arr.length][aim + 1];

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

for (int j = 1; arr[0] * j <= aim; j++)

int num = 0;

for (int i = 1; i < arr.length; i++)

dp[i][j] = num;

}} return dp[arr.length - 1][aim];

}

五、動態規劃的優化

上的已經差不多了,只不過k的那裡使用的是列舉

這些效率不高,利用數值之間的關係進行優化如下

public static int coins4(int arr, int aim) 

int dp = new int[arr.length][aim + 1];

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

for (int j = 1; arr[0] * j <= aim; j++)

for (int i = 1; i < arr.length; i++)

} return dp[arr.length - 1][aim];

}

動態規劃典型例題

題目描述 一天,ykc在學校閒的無聊,於是決定上街買點吃的,ykc很懶,本來就不是很像逛街,於是找來了czl幫他買,這裡應該有滑稽,而czl也不願為ykc買東西吃,但是ykc很強勢,非讓他去買,呢沒辦法了,然而czl還有很多事要做,沒呢麼多時間幫ykc,而這條小吃街又很長,有n家店,n有50000這...

動態規劃幾個典型題總結

這是典型的三道動態規劃,在筆試當中,有可能會被舉一反三地考。1 求乙個陣列最大連續子陣列之和。示例 int nums 最大連續子陣列是2,1,3,6,所以輸出12。2 求乙個陣列的最長遞增子串行。示例 int nums 最長遞增子串行是1,3,6,所以輸出3。3 求兩個字串的最大公共子串。示例 st...

動態規劃典型例題解析

動態規劃的主要思想是把問題劃分為乙個個子狀態,乙個狀態的最優解往往是基於其前乙個狀態的最優解。兩個狀態之間的關係,我們就稱之為狀態轉移方程。這裡引出了狀態和狀態轉移方程的概念 狀態是乙個當前的值,這個值是通過前乙個值以及狀態轉移方程推得的。在解決動態規劃問題的時候,我們往往會把問題建模為乙個一維陣列...