robber问题的动态规划解法

来源:互联网 发布:知乎为什么会被邀请 编辑:程序博客网 时间:2024/05/19 14:39

接上一篇:http://blog.csdn.net/coronia/article/details/73173765


在此之后,本人在一次测试中也遇到了类似的问题。这一次,我参考了该题的思路并写下了如下动态规划方法:


06.classSolution {
07.public:
08.    intmaxSum(vector<int>& A) {
09.        inta = 0;
10.        intb = 0;
11.         
12.        for(int i = 0; i < A.size(); i++) {
13.            if(i % 2==0) {
14.                a = max(a + A[i], b);
15.            }
16.            else{
17.                b = max(a, b + A[i]);
18.            }
19.        }
20.     
21.        returnmax(a, b);
22.    }
23.};

首先将问题分为子问题。之前也说过,这种跳跃式选择的情况不外乎种:一次间隔两个或三个。最后一次选择的结果也无非是两种:最后一项或倒数第二项,而再往前推也是如此。因此可以考虑根据单双数来进行划分:对于某一个元素,是选择它的前两项(双数)还是三项(单数)。这样递推下去,可知起始点也只有两种情况:第一位或第二位。

接下来考虑关联公式。对于某一个与上一选取点间隔两个的点,可以有两种情况:选取它,或是选取它之后的那个点。于是,要比较的就是这两种情况谁更大。同样地,其他的点也要用这种递归调用。注意到如果是一直取间隔为2的点,就会一直维持在奇数点或偶数点下,因此可以分别用两个变量来记录这两者;而当取三个的时候,我们可以发现原本的奇数点就要取偶数点,因此可以直接将偶数对应的变量拿去比较即可。奇数同理