大家好,欢迎来到IT知识分享网。
一、动态规划简介
- 动态规划可以用一句话概括:
动态规划是在解决多阶决策的过程中动态地选择最优决策的方法
- 最终目的:找出最优解
- 问题特征:
(1). 问题范围可以缩小到多个问题单元,对应多种决策
(2). 这多个决策动态选择组合可以充分解决整个问题 - 解决问题三要素:
(1). 最优子决策
(2). 边界值
(3). 状态抉择公式
二、线性模型
例子:小朋友过桥
四个调皮的小朋友晚上要过桥去对岸玩耍。桥一次最多只能通过两个小朋友,他们只有一个手电筒,过桥需要有人拿着手电筒,问他们怎么过最快。其中这四个小朋友的过桥速度分别为1,2,5,10 (分钟)
有的人会想到贪心算法(只要一个策略作为最优策略):速度最快的小朋友来回传手电筒,那么有什么欠考虑的地方呢?我们一起来看一下过程图:
【贪心算法过程图】
【动态规划过程图】
图1算出19,图2算出17,相信你已经发现,一起走的两个人,如果速度相当,反而会节约时间。如果你害怕还有欠考虑的情况,那就直接用动态规划思路吧,一起来看看。
三、动态规划步骤(自底向上):
先将小朋友按照速度快慢进行排列得到队列:
t[i]={t(1),t(2),t(3)…t(i)}
1.找出边界:
最后剩下两个小朋友、最后剩下1个小朋友
2.找出边界对应最优子决策:
最后剩下1个小朋友:
remainOne(i)=sum(i)=sum(i-1)+t(1)+t(i)
最后剩下两个小朋友:
remainTwo(i)=sum(i)=sum(i-2)+t(1)+t(i)+t(2)+t(2)
3.状态抉择:
sum(i)=min(remainOne(i),remainTwo(i))
四、送上完整java实现代码
public class AlgorithmTest {
public static int[] childTimes=new int[]{
1,2,5,10};//{2,4,5,7};
public static int indexFirst=0;
public static int indexSecond=1;
public static void main(String[] args) {
AlgorithmTest test=new AlgorithmTest();
System.out.println(test.getSumTime(4-1));
System.out.println(test.getSumTimeFor());
}
//递归方式
public int getSumTime(int i) {
if (i <=indexSecond) {
if(childTimes.length==1){
return childTimes[indexFirst];
}
return childTimes[indexSecond];
}
//如果只剩下一个,那么总耗时=i-1个人之前的总耗时+一个来回(送电筒的+最后一个的)
int lastone = getSumTime(i - 1) + childTimes[indexFirst] + childTimes[i];
int lasttwo = getSumTime(i - 2) + childTimes[indexFirst] + childTimes[i] + childTimes[indexSecond] + childTimes[indexSecond];
return Math.min(lastone, lasttwo);
}
//备忘录方式
public int getSumTimeFor(){
int[] memoMin=new int[childTimes.length];
int memoRemainOne=0;
int memoRemainTwo=0;
int n=childTimes.length-1;
if (n ==indexFirst||n==indexSecond) {
if(childTimes.length==1){
memoMin[0]= childTimes[indexFirst];
}
memoMin[0]= childTimes[indexSecond];
return memoMin[0];
}
memoMin[0]=memoMin[1]= childTimes[indexSecond];
for (int i=2;i<=n;i++){
memoRemainOne=memoMin[i-1] + childTimes[indexFirst] + childTimes[i];
memoRemainTwo=(memoMin[i-2])+ childTimes[indexFirst] + childTimes[i] + childTimes[indexSecond] + childTimes[indexSecond];
memoMin[i]=Math.min(memoRemainOne, memoRemainTwo);
}
return memoMin[n];
}
}
最后输出:
17
17
集合为{2,4,5,7}则输出:
20
20
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/11542.html