您的位置:首页 > 职场人生

(动态规划DP)面试题:求数组中两个数的最大差值(只能下标大的减去下标小的)符合无后效性

2013-09-18 01:42 1191 查看
空间复杂度优化算法

void sovle_maxSub_Dp_OptimalSpace(int *a, int n){
int S=0;
int max_value=INT_MIN;
int max_index=0;
for(int i=n-2;i>=1;i--){
S=S<0?a[i]-a[i+1]:a[i]-a[i+1]+S;
if(max_value<S){
max_value=S;
max_index=i;
}
}
cout<<"最大差值为:"<<max_value<<",对应的两个元素为:"<<endl;
cout<<"数组中第"<<max_index<<"个元素:"<<a[max_index]<<endl;
for(int i=max_index+1;i<=n;i++){
if(a[max_index]-a[i]==max_value){
cout<<"数组中第"<<i<<"个元素:"<<a[i]<<endl;
break;
}
}
}


当时头大,只写了穷举法 O(N2)的复杂度,肯定还有简单的方法呀,只是当时不知怎地就是想不起来紧张的要死告诉面试官暂时另一个办法想不起来了

回来一看又是编程之美里的题目,其实我在暑假的时候已经看过了那个题目可惜可惜。现在在这里写出来给自己一个经验教训!

动态规划算法O(N)

给定一个整数数组,a[1],a[2],...,a
,每一个元素a[i]可以和它右边的(a[i+1],a[i+2],...,a
)元素做差,求这个数组中最大的差值,例如a={0,3,9,1,3,5}这个数组最大的差值就是9-1=8;(此为小减大,面试给的是大减小)

利用DP的思想,定义S[i]为a[i]与其右边元素之差的最大值,那么状态转移方程为:

s[i]=a[i]-a[i+1] if s[i+1]<0 (表明a[i+1]是从i+1到n所有元素中最小的一个)

s[i]=s[i+1]+a[i]-a[i+1] if s[i+1]>=0

动态规划

一,动态规划三要素:阶段,状态,决策。

如果把动态规划的求解过程看成一个工厂的生产线,阶段就是生产某个商品的不同的环节,状态就是工件当前的形态,决策就是对工件的操作。显然不同阶段是对产品的一个前面各个状态的小结,有一个个的小结构成了最终的整个生产线。每个状态间又有关联(下一个状态是由上一个状态做了某个决策后产生的)。

下面举个例子:

要生产一批雪糕,在这个过程中要分好多环节:购买牛奶,对牛奶提纯处理,放入工厂加工,加工后的商品要包装,包装后就去销售……,这样没个环节就可以看做是一个阶段;产品在不同的时候有不同的状态,刚开始时只是白白的牛奶,进入生产后做成了各种造型,从冷冻库拿出来后就变成雪糕(由液态变成固态)。每个形态就是一个状态,那从液态变成固态经过了冰冻这一操作,这个操作就是一个决策。

一个状态经过一个决策变成了另外一个状态,这个过程就是状态转移,用来描述状态转移的方程就是状态转移方程。

经过这个例子相信大家对动态规划有所了解了吧。

下面在说说我对动态规划的另外一个理解:

用图论知识理解动态规划:把动态规划中的状态抽象成一个点,在有直接关联的状态间连一条有向边,状态转移的代价就是边上的权。这样就形成了一个有向无环图AOE网(为什么无环呢?往下看)。对这个图进行拓扑排序,删除一个边后同时出现入度为0的状态在同一阶段。这样对图求最优路径就是动态规划问题的求解。

二,动态规划的适用范围

动态规划用于解决多阶段决策最优化问题,但是不是所有的最优化问题都可以用动态规划解答呢?

一般在题目中出现求最优解的问题就要考虑动态规划了,但是否可以用还要满足两个条件:

1)最优子结构(最优化原理)

2)无后效性

最优化原理在下面的最短路径问题中有详细的解答;

什么是无后效性呢?

就是说在状态i求解时用到状态j而状态j就解有用到状态k…..状态N。

而求状态N时有用到了状态i这样求解状态的过程形成了环就没法用动态规划解答了,这也是上面用图论理解动态规划中形成的图无环的原因。

也就是说当前状态是前面状态的完美总结,现在与过去无关。。。

当然,有是换一个划分状态或阶段的方法就满足无后效性了,这样的问题仍然可以用动态规划解。

三,动态规划解决问题的一般思路。

拿到多阶段决策最优化问题后,第一步要判断这个问题是否可以用动态规划解决,如果不能就要考虑搜索或贪心了。当却定问题可以用动态规划后,就要用下面介绍的方法解决问题了:

(1)模型匹配法:

最先考虑的就是这个方法了。挖掘问题的本质,如果发现问题是自己熟悉的某个基本的模型,就直接套用,但要小心其中的一些小的变动,现在考题办都是基本模型的变形套用时要小心条件,三思而后行。这些基本模型在先面的分类中将一一介绍。

(2)三要素法

仔细分析问题尝试着确定动态规划的三要素,不同问题的却定方向不同:

先确定阶段的问题:数塔问题,和走路问题(详见解题报告)

先确定状态的问题:大多数都是先确定状态的。

先确定决策的问题:背包问题。(详见解题报告)

一般都是先从比较明显的地方入手,至于怎么知道哪个明显就是经验问题了,多做题就会发现。

(3)寻找规律法:

这个方法很简单,耐心推几组数据后,看他们的规律,总结规律间的共性,有点贪心的意思。

(4)边界条件法

找到问题的边界条件,然后考虑边界条件与它的领接状态之间的关系。这个方法也很起效。

(5)放宽约束和增加约束

这个思想是在陈启锋的论文里看到的,具体内容就是给问题增加一些条件或删除一些条件使问题变的清晰。

动态规划是解决多决策问题最优化问题的一种良好算法,典型的DP应用就是背包问题,图像压缩问题等,DP可以决解决贪心算法和分而治之问题中一些难以解决的问题
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: