码迷,mamicode.com
首页 > 其他好文 > 详细

Lintcode: Minimum Adjustment Cost 解题报告

时间:2014-12-09 19:18:19      阅读:363      评论:0      收藏:0      [点我收藏+]

标签:des   cWeb   cPage   style   blog   http   io   ar   color   

Minimum Adjustment Cost

Given an integer array, adjust each integers so that the difference of every adjcent integers are not greater than a given number target.

If the array before adjustment is A, the array after adjustment is B, you should minimize the sum of |A[i]-B[i]| 

注意

You can assume each number in the array is a positive integer and not greater than 100

样例

Given [1,4,2,3] and target=1, one of the solutions is [2,3,2,3], the adjustment cost is 2 and it‘s minimal. Return 2.

 

原题链接:http://lintcode.com/zh-cn/problem/minimum-adjustment-cost/#

 bubuko.com,布布扣

SOL 1:

主页君现在最喜欢这种题目了。好兴奋啊!

好啦,我们先上第一个版本,递归版本:

当前可取的值是1-100,并且与上一个值是在target的差值以内。

这个版本肯定是超时啦。因为我们有大量的重复的计算,每一次从头至尾计算时,从某个index开始的某个取值的计算会反复进行。

bubuko.com,布布扣
 1 /**
 2      * @param A: An integer array.
 3      * @param target: An integer.
 4      */
 5     public static int MinAdjustmentCost1(ArrayList<Integer> A, int target) {
 6         // write your code here
 7         if (A == null) {
 8             return 0;
 9         }
10         
11         return rec(A, new ArrayList<Integer>(A), target, 0);
12     }
13     
14     /*
15      * SOL 1:
16      * 最普通的递归方法。
17      * */
18     public static int rec(ArrayList<Integer> A, ArrayList<Integer> B, int target, int index) {
19         int len = A.size();
20         if (index >= len) {
21             // The index is out of range.
22             return 0;
23         }
24         
25         int dif = 0;
26         
27         int min = Integer.MAX_VALUE;
28         
29         // If this is the first element, it can be from 1 to 100;
30         for (int i = 0; i <= 100; i++) {
31             if (index != 0 && Math.abs(i - B.get(index - 1)) > target) {
32                 continue;
33             }
34             
35             B.set(index, i);
36             dif = Math.abs(i - A.get(index));
37             dif += rec(A, B, target, index + 1);
38             min = Math.min(min, dif);
39             
40             // 回溯
41             B.set(index, A.get(index));
42         }
43         
44         return min;
45     }
View Code

 

SOL 2:

我们还是跟以前一样,加一个memory,减少重复计算。

轻松AC. M[i][j]的定义是:从index = i处开始往后所有的differ,并且A[i]的取值取为j + 1;

bubuko.com,布布扣
 1 /*
 2      * 递归2:
 3      * Rec + memory.
 4      * */
 5     /**
 6      * @param A: An integer array.
 7      * @param target: An integer.
 8      */
 9     public static int MinAdjustmentCost2(ArrayList<Integer> A, int target) {
10         // write your code here
11         if (A == null || A.size() == 0) {
12             return 0;
13         }
14         
15         int[][] M = new int[A.size()][100];
16         for (int i = 0; i < A.size(); i++) {
17             for (int j = 0; j < 100; j++) {
18                 M[i][j] = Integer.MAX_VALUE;
19             }
20         }
21         
22         return rec2(A, new ArrayList<Integer>(A), target, 0, M);
23     }
24     
25     public static int rec2(ArrayList<Integer> A, ArrayList<Integer> B, int target, int index, 
26            int[][] M) {
27         int len = A.size();
28         if (index >= len) {
29             // The index is out of range.
30             return 0;
31         }
32         
33         int dif = 0;
34         int min = Integer.MAX_VALUE;
35         
36         // If this is the first element, it can be from 1 to 100;
37         for (int i = 1; i <= 100; i++) {
38             if (index != 0 && Math.abs(i - B.get(index - 1)) > target) {
39                 continue;
40             }
41             
42             if (M[index][i - 1] != Integer.MAX_VALUE) {
43                 dif = M[index][i - 1];
44                 min = Math.min(min, dif);
45                 continue;
46             }
47             
48             B.set(index, i);
49             dif = Math.abs(i - A.get(index));
50             dif += rec2(A, B, target, index + 1, M);
51             
52             min = Math.min(min, dif);
53             
54             // Record the result.
55             M[index][i - 1] = dif;
56             
57             // 回溯
58             B.set(index, A.get(index));
59         }
60         
61         return min;
62     }
View Code

 

SOL 3:修改了一下,递归增加一个参数 : int x,表示在index 处A[i]取值为x,返回值的意义是,当此值取x时,从index往后,所有的diff之和。

这样的话,递归会看起来更加简洁一点儿。我们不需要记录上一个A[i]的取值。

 

bubuko.com,布布扣
 1 /*
 2      * SOLUTION 3 递归2:
 3      * Rec + memory.
 4      * 改进的递归版本
 5      * */
 6     /**
 7      * @param A: An integer array.
 8      * @param target: An integer.
 9      */
10     public static int MinAdjustmentCost3(ArrayList<Integer> A, int target) {
11         // write your code here
12         if (A == null || A.size() == 0) {
13             return 0;
14         }
15         
16         int[][] M = new int[A.size()][100];
17         for (int i = 0; i < A.size(); i++) {
18             for (int j = 0; j < 100; j++) {
19                 M[i][j] = Integer.MAX_VALUE;
20             }
21         }
22         
23         // 首个数字可以取1-100
24         int min = Integer.MAX_VALUE;
25         for (int i = 1; i <= 100; i++) {
26             min = Math.min(min, rec3(A, target, 0, i, M));
27         }
28         
29         return min;
30     }
31     
32     /*
33      * 将当前值设置为x能求得的最小解 
34      * */
35     public static int rec3(ArrayList<Integer> A, int target, int index, int x, 
36            int[][] M) {
37         int len = A.size();
38         if (index >= len) {
39             // The index is out of range.
40             return 0;
41         }
42         
43         if (M[index][x - 1] != Integer.MAX_VALUE) {
44             return M[index][x - 1];
45         }
46         
47         int bas = Math.abs(x - A.get(index));
48         int min = Integer.MAX_VALUE;
49         
50         // 对下一个值尝试取1-100
51         for (int i = 1; i <= 100; i++) {
52             // 下一个值的取值不可以超过abs
53             if (index != len - 1 && Math.abs(i - x) > target) {
54                 continue;
55             }
56             
57             // 计算dif 
58             int dif = bas + rec3(A, target, index + 1, i, M);
59             min = Math.min(min, dif);
60         }
61         
62         // Record the result.
63         M[index][x - 1] = min;
64         return min;
65     }
View Code

 

SOL 4:

LALA,主页君终于来打BOSS了。有了前面的递归的铺垫,把它转化为一个二维DP也就是水到渠成了。

D[i][v]: 把index = i的值修改为v,所需要的最小花费

我们引用一下九章算法黄老师课上的课件:

其实很简单,就是当前index为v时,我们把上一个index从1-100全部过一次,取其中的最小值(判断一下前一个跟当前的是不是abs <= target)

bubuko.com,布布扣

bubuko.com,布布扣
 1 /*
 2      * SOLUTION 4:
 3      * DP
 4      * */
 5     /**
 6      * @param A: An integer array.
 7      * @param target: An integer.
 8      */
 9     public static int MinAdjustmentCost(ArrayList<Integer> A, int target) {
10         // write your code here
11         if (A == null || A.size() == 0) {
12             return 0;
13         }
14         
15         // D[i][v]: 把index = i的值修改为v,所需要的最小花费
16         int[][] D = new int[A.size()][101];
17         
18         int size = A.size();
19         
20         for (int i = 0; i < size; i++) {
21             for (int j = 1; j <= 100; j++) {
22                 D[i][j] = Integer.MAX_VALUE;
23                 if (i == 0) {
24                     // The first element.
25                     D[i][j] = Math.abs(j - A.get(i));
26                 } else {
27                     for (int k = 1; k <= 100; k++) {
28                         // 不符合条件 
29                         if (Math.abs(j - k) > target) {
30                             continue;
31                         }
32                         
33                         int dif = Math.abs(j - A.get(i)) + D[i - 1][k];
34                         D[i][j] = Math.min(D[i][j], dif);
35                     }
36                 }
37             }
38         }
39         
40         int ret = Integer.MAX_VALUE;
41         for (int i = 1; i <= 100; i++) {
42             ret = Math.min(ret, D[size - 1][i]);
43         }
44         
45         return ret;
46     }
View Code

 

GITHUB:

https://github.com/yuzhangcmu/LeetCode_algorithm/blob/master/algorithm/dp/MinAdjustmentCost_Class.java

Lintcode: Minimum Adjustment Cost 解题报告

标签:des   cWeb   cPage   style   blog   http   io   ar   color   

原文地址:http://www.cnblogs.com/yuzhangcmu/p/4153927.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!