大家好,今天我们一起来看一下这道动态规划的题目,子数组最大乘积
思路
这道题目中子数组是连续的,求某一个连续的乘积是最大的。
这道题不知道如何使用dp加快速度,因为我选择的状态转移是有点复杂的。
他的两个状态:选过/没有选过
他的两个状态:往后走/不往后走
a往后走 1. 选这个2.不选这个
b不往后走 1. 选这个 2 不选这个
但是注意b2这个选项,如果不往后走,也不选的话,相当于没有东西,但是我们是要求至少有一个数的 所以b2的情况是可以省略的 共计三种选择 a1,a2,b1,b2(BE CAREFUl)
列情况:
如果没有选过的话,有三个选择
a1,a2,b1
如果选过了的话,只有两个选择,
a1,b1 因为a2的不选这个并且往后走是不可以的
具体代码请看下表
Thought:可以注意到在pro方法里面,pre作为一个变量是保存在里面的,但是我们最终要返回的不正是pre变量所表达的意思吗?
这里没有将其拆分,是因为做决策的时候需要它的存在,也就是历史的影响(historial Affect),现阶段无法将这个变量划分出去,只能让它存在下去,ps2021.5.4
public double maxProduct(double[] arr) {
if (arr == null || arr.length < 1)return 0;
if (arr.length == 1) {
return arr[0];
}
return pro(arr,0,1,false);
}
public static double pro(double[] a,int index,double pre,boolean xuanle){
if(index < 0 || index > a.length) return 0;
//if(a[index] == 0) return;
if(index == a.length-1) {
if(!xuanle) {// 没选过
return a[index];
}else {
//选过
return Math.max(pre * a[index],pre);
}
}
if(!xuanle) {
// 之前没有选过数字 选? / 直接停止 ?
// 往后走
double p1 = pro(a,index+1,pre,false); // 不选这一个,看下一个
double p2 = pro(a,index+1,pre*a[index],true); // 要选这个,继续往后走
// 不往后走了
double p3 = pre*a[index];// 不选后面的,但这个我要选(因为至少要选一个)
return Math.max(Math.max(p1,p2),p3);
}else { //之前选过数字了 继续选? / 停止?
double p3 = pro(a,index+1,pre*a[index],true); // 要选这个,继续往后走
return Math.max(p3, pre*a[index]);
}
}