生活随笔
收集整理的這篇文章主要介紹了
动态规划——坐标型位操作型
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
動態規劃——坐標型&位操作型
坐標型動態規劃——帶阻礙的唯一路徑序列型動態規劃——油漆房子劃分型動態規劃——解密方式坐標型動態規劃——最長上升連續子序列坐標型動態規劃——最小路徑和坐標型動態規劃——炸彈襲擊位操作型動態規劃——計算二進制中 1 的個數
1. 坐標型動態規劃——帶阻礙的唯一路徑
https://www.lintcode.com/problem/unique-paths-ii/description
題目描述:
- 給定 m 行 n 列的網格,有一個機器人從左上角(0,0)出發,每一步可以向下或者向右走一步。
- 網格中有些地方有障礙,機器人不能通過障礙格。
- 問有多少種不同的方式走到右下角?
public int uniquePathsWithObstacles(int[][] board
) {int m
= board
.length
;int n
= board
[0].length
;if (m
== 0 || n
== 0) {return 0;}int[][] f
= new int[m
][n
];for (int i
= 0; i
< m
; i
++) {for (int j
= 0; j
< n
; j
++) {if (board
[i
][j
] == 1) {f
[i
][j
] = 0;continue;}if (i
== 0 || j
== 0) {f
[i
][j
] = 1;continue;}if (i
> 0) {f
[i
][j
] += f
[i
- 1][j
];}if (j
> 0) {f
[i
][j
] += f
[i
][j
- 1];}}}return f
[m
- 1][n
- 1];}
2. 序列型動態規劃——油漆房子
https://www.lintcode.com/problem/paint-house/description
題目描述:
- 有一排 N 棟房子,每棟房子要涂成 3 種顏色中的一種:紅、藍、綠。
- 任何兩棟相鄰房子不能涂成相同的顏色
- 第 i 棟房子染成紅色、藍色、綠色的花費分別是 cost[i][0],cost[i][1],cost[i][2]
- 問最少需要花多少錢油漆這些房子?
public int minCost(int[][] c
) {int n
= c
.length
;if (n
== 0) {return 0;}int[][] f
= new int[n
+ 1][3];f
[0][0] = f
[0][1] = f
[0][2] = 0;for (int i
= 1; i
<= n
; i
++) {for (int j
= 0; j
< 3; j
++) {f
[i
][j
] = Integer
.MAX_VALUE
;for (int k
= 0; k
< 3; k
++) {if (j
!= k
) {f
[i
][j
] = Math
.min(f
[i
][j
], f
[i
- 1][k
] + c
[i
- 1][j
]);}}}}return Math
.min(f
[n
][0], Math
.min(f
[n
][1], f
[n
][2]));}
3. 劃分型動態規劃——解密方式
https://www.lintcode.com/problem/decode-ways/description
題目描述:
- 有一段由 A-Z 組成的字符串信息被加密成數字串。
- 加密方式為:A->1, B->2, …Z->26
- 給定加密后的數字串 S[0…N-1],問有多少種方式解密成字符串?
public int numDecodings(String ss
) {char[] s
= ss
.toCharArray();int n
= s
.length
;if (n
== 0) {return 0;}int[] f
= new int[n
+ 1];f
[0] = 1;int i
, j
;for (i
= 1; i
<= n
; i
++) {f
[i
] = 0;if (s
[i
- 1] >= '1' && s
[i
- 1] <= '9') {f
[i
] += f
[i
- 1];}if (i
> 1) {j
= 10 * (s
[i
- 2] - '0') + (s
[i
- 1] - '0');if (j
>= 10 && j
<= 26) {f
[i
] += f
[i
- 2];}}}return f
[n
];}
4. 坐標型動態規劃——最長上升連續子序列
題目描述:
- 給定 a[0],…,a[n-1]
- 找到最長的連續子序列 i,i+1,i+2,…j,使得 a[i] < a[i+1] < a[j],或者 a[i] > a[i+1] > …>a[j],輸出長度 j-i+1.
例子:
輸入:[5,1,2,3,4]
輸出:4(子序列 1,2,3,4)
public int longestIncreasingContinuousSubsequence(int[] nums
) {int n
= nums
.length
;if (n
== 0) {return 0;}int r1
= LIS(nums
, n
);int i
, j
, temp
;i
= 0;j
= n
- 1;while (i
< j
) {temp
= nums
[i
];nums
[i
] = nums
[j
];nums
[j
] = temp
;i
++;j
--;}int r2
= LIS(nums
, n
);return r1
>= r2
? r1
: r2
;}private int LIS(int[] nums
, int n
) {int i
;int[] f
= new int[n
];int res
= 0;for (i
= 0; i
< n
; i
++) {f
[i
] = 1;if (i
> 0 && nums
[i
] > nums
[i
- 1]) {f
[i
] = f
[i
- 1] + 1;}res
= Math
.max(res
, f
[i
]);}return res
;}
5. 坐標型動態規劃——最小路徑和
https://www.lintcode.com/problem/minimum-path-sum/description
題目描述:
- 給定 m 行 n 列的網格,每個格子(i,j)里都一個非負數 A[i][j]
- 求一個左上角(0,0)到右下角的路徑,每一步只能向下或者向右走一步,使得路徑上的格子里的數字之和最小
- 輸出最小數字和
public int minPathSum(int[][] board
) {int m
= board
.length
;int n
= board
[0].length
;if (m
== 0 || n
== 0) {return 0;}int[][] f
= new int[m
][n
];for (int i
= 0; i
< m
; i
++) {for (int j
= 0; j
< n
; j
++) {if (i
== 0 && j
== 0) {f
[i
][j
] = board
[0][0];continue;}int t
= Integer
.MAX_VALUE
;if (i
> 0) {t
= Math
.min(t
, f
[i
- 1][j
] );}if (j
> 0) {t
= Math
.min(t
, f
[i
][j
- 1] );}f
[i
][j
] = t
+board
[i
][j
];}}return f
[m
-1][n
-1];}
滾動數組方式:將 f 的 i 位置 %2.
public int minPathSum(int[][] board
) {int m
= board
.length
;int n
= board
[0].length
;if (m
== 0 || n
== 0) {return 0;}int[][] f
= new int[2][n
];for (int i
= 0; i
< m
; i
++) {for (int j
= 0; j
< n
; j
++) {if (i
== 0 && j
== 0) {f
[i
% 2][j
] = board
[0][0];continue;}int t
= Integer
.MAX_VALUE
;if (i
> 0) {t
= Math
.min(t
, f
[1 - i
% 2][j
]);}if (j
> 0) {t
= Math
.min(t
, f
[i
% 2][j
- 1]);}f
[i
% 2][j
] = t
+ board
[i
][j
];}}return f
[(m
- 1) % 2][n
- 1];}
6. 坐標型動態規劃——炸彈襲擊
https://www.lintcode.com/problem/bomb-enemy/description
題目描述:
- 有一個 M*N 的網格,每個格子可能是空的,可能有一個敵人,可能有一堵墻
- 只能在某個空格子里放一個炸彈,炸彈會炸死所有同行同列的敵人,但是不能穿透墻
- 最多能炸死幾個敵人
public int maxKilledEnemies(char[][] A
) {if (A
== null
|| A
.length
== 0 || A
[0].length
== 0) {return 0;}int m
= A
.length
;int n
= A
[0].length
;int[][] up
= new int[m
][n
];int[][] down
= new int[m
][n
];int[][] left
= new int[m
][n
];int[][] right
= new int[m
][n
];int i
, j
, t
;for (i
= 0; i
< m
; ++i
) {for (j
= 0; j
< n
; ++j
) {up
[i
][j
] = 0;if (A
[i
][j
] != 'W') {if (A
[i
][j
] == 'E') {up
[i
][j
] = 1;}if (i
- 1 >= 0) {up
[i
][j
] += up
[i
-1][j
];}}}}for (i
= m
- 1; i
>= 0; --i
) {for (j
= 0; j
< n
; ++j
) {down
[i
][j
] = 0;if (A
[i
][j
] != 'W') {if (A
[i
][j
] == 'E') {down
[i
][j
] = 1;}if (i
+ 1 < m
) {down
[i
][j
] += down
[i
+1][j
];}}}}for (i
= 0; i
< m
; ++i
) {for (j
= 0; j
< n
; ++j
) {left
[i
][j
] = 0;if (A
[i
][j
] != 'W') {if (A
[i
][j
] == 'E') {left
[i
][j
] = 1;}if (j
- 1 >= 0) {left
[i
][j
] += left
[i
][j
-1];}}}}for (i
= 0; i
< m
; ++i
) {for (j
= n
- 1; j
>= 0; --j
) {right
[i
][j
] = 0;if (A
[i
][j
] != 'W') {if (A
[i
][j
] == 'E') {right
[i
][j
] = 1;}if (j
+ 1 < n
) {right
[i
][j
] += right
[i
][j
+1];}}}}int res
= 0;for (i
= 0; i
< m
; ++i
) {for (j
= 0; j
< n
; ++j
) {if (A
[i
][j
] == '0') {t
= up
[i
][j
] + down
[i
][j
] + left
[i
][j
] + right
[i
][j
];res
= Math
.max(res
,t
);}}}return res
;}
7. 位操作型動態規劃——計算二進制中 1 的個數
https://www.lintcode.com/problem/counting-bits/description
題目描述:
- 給定 N,要求輸出 0,1,…,N 的每個數的二進制表示里1 的個數。
public int[] countBits(int num
) {int[] f
= new int[num
+ 1];f
[0] = 0;for (int i
= 1; i
<= num
; i
++) {f
[i
] = (i
% 2) + f
[i
>> 1];}return f
;}
總結
以上是生活随笔為你收集整理的动态规划——坐标型位操作型的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。