生活随笔
收集整理的這篇文章主要介紹了
数据结构与算法之暴力递归改动态规划
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
數據結構與算法之暴力遞歸改動態規劃
目錄
二維數組最小路徑和暴力遞歸改動態規劃解析任意選擇數組arr中的數字,看能不能累加得到aim
1. 二維數組最小路徑和
(一) 題目描述
(二) 思路
遞歸版 如果 i == matrix.length && j == matrix[0].length,說明到了右下角,返回即可。如果 i == matrix.length - 1,說明到了最后一行,只能向右走如果 j == matrix[0].length - 1,說明到了最后一列,只能向下走獲取向右走和向下走的最短路徑和。取向右走和向下走中小的一個加入當前點即為最短路徑和。(每一步都是如此)
public static int walk(int[][] matrix
, int i
, int j
) {if (i
== matrix
.length
&& j
== matrix
[0].length
) {return matrix
[i
][j
];}if (i
== matrix
.length
- 1) {return matrix
[i
][j
] + walk(matrix
, i
, j
+ 1);}if (j
== matrix
[0].length
- 1) {return matrix
[i
][j
] + walk(matrix
, i
+ 1, j
);}int right
= walk(matrix
, i
, j
+ 1);int down
= walk(matrix
, i
+ 1, j
);return matrix
[i
][j
] + Math
.min(right
, down
);}
2. 暴力遞歸改動態規劃解析
什么樣的嘗試版本可以改動態規劃?
當遞歸過程中發現有重復狀態,而且重復狀態與到達的路徑是沒有關系的,那么一定可以改動態規劃就是說,(0,0)到(1,1),不管(0,0)是向右走再向下走,還是向下走再向右走到達(1,1)(1,1)的最短路徑還是不會變,叫無后效性問題。參數固定了,返回值一定是固定的,就是無后效性問題。
因為 i,j的變化范圍我們知道,是一張二維表。所以所有的返回值肯定都在這個表里面。也就是說,可以在一張表中
把需要的位置點出來回到base case中,把不被依賴的值設置好回到遞歸中,發現假設當前點是(i,j),一個普遍的位置需要右邊的狀態和下邊的狀態推出普遍位置依賴之后,反過去就是計算順序,最后一行弄好,從右到左,從下到上依次推到頂部就是答案。這就是暴力遞歸改動態規劃的統一套路如上個題:
總的就是說
寫出嘗試版本分析可變參數,分析哪幾個參數可以代表返回值狀態,可變參數是幾維的,它就是幾維表看看最終的狀態是哪一個,在表中點出來,然后回到base case中,把不依賴的值設置好,看看一個普遍位置需要哪些位置,逆著回去,就是填表的順序,這就是暴力遞歸改動態規劃 上述題由暴力遞歸改動態規劃代碼實現為
public static int minPath1(int[][] matrix
) {return process1(matrix
, matrix
.length
- 1, matrix
[0].length
- 1);}public static int process1(int[][] matrix
, int i
, int j
) {int res
= matrix
[i
][j
];if (i
== 0 && j
== 0) {return res
;}if (i
== 0 && j
!= 0) {return res
+ process1(matrix
, i
, j
- 1);}if (i
!= 0 && j
== 0) {return res
+ process1(matrix
, i
- 1, j
);}return res
+ Math
.min(process1(matrix
, i
, j
- 1), process1(matrix
, i
- 1, j
));}public static int minPath2(int[][] m
) {if (m
== null
|| m
.length
== 0 || m
[0] == null
|| m
[0].length
== 0) {return 0;}int row
= m
.length
;int col
= m
[0].length
;int[][] dp
= new int[row
][col
];dp
[0][0] = m
[0][0];for (int i
= 1; i
< row
; i
++) {dp
[i
][0] = dp
[i
- 1][0] + m
[i
][0];}for (int j
= 1; j
< col
; j
++) {dp
[0][j
] = dp
[0][j
- 1] + m
[0][j
];}for (int i
= 1; i
< row
; i
++) {for (int j
= 1; j
< col
; j
++) {dp
[i
][j
] = Math
.min(dp
[i
- 1][j
], dp
[i
][j
- 1]) + m
[i
][j
];}}return dp
[row
- 1][col
- 1];}
3. 任意選擇數組arr中的數字,看能不能累加得到aim
題目描述
代碼實現
public class Code_08_Money_Problem {public static boolean money1(int[] arr
, int aim
) {return process1(arr
, 0, 0, aim
);}public static boolean process1(int[] arr
, int i
, int sum
, int aim
) {if (sum
== aim
) {return true;}if (i
== arr
.length
) {return false;}return process1(arr
, i
+ 1, sum
, aim
) || process1(arr
, i
+ 1, sum
+ arr
[i
], aim
);}public static boolean money2(int[] arr
, int aim
) {boolean[][] dp
= new boolean[arr
.length
+ 1][aim
+ 1];for (int i
= 0; i
< dp
.length
; i
++) {dp
[i
][aim
] = true;}for (int i
= arr
.length
- 1; i
>= 0; i
--) {for (int j
= aim
- 1; j
>= 0; j
--) {dp
[i
][j
] = dp
[i
+ 1][j
];if (j
+ arr
[i
] <= aim
) {dp
[i
][j
] = dp
[i
][j
] || dp
[i
+ 1][j
+ arr
[i
]];}}}return dp
[0][0];}public static void main(String
[] args
) {int[] arr
= { 1, 4, 8 };int aim
= 12;System
.out
.println(money1(arr
, aim
));System
.out
.println(money2(arr
, aim
));}}
總結
以上是生活随笔為你收集整理的数据结构与算法之暴力递归改动态规划的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。