java – 使用动态编程删除中间元素的三元组产品的最小总和
作者:互联网
我给出了一系列N个数(4≤N≤150).挑选一个索引i(0 使用以下顺序的索引:1-> 3-> 4-> 5-> 2这是总和:
44 * 45 * 5 5 * 39 * 15 5 * 15 * 22 5 * 22 * 10 44 * 5 * 10 = 9900 2925 1650 1100 2200 = 17775
我找到了一个使用递归函数的解决方案:
public static int smallestSum(List<Integer> values) {
if (values.size() == 3)
return values.get(0) * values.get(1) * values.get(2);
else {
int ret = Integer.MAX_VALUE;
for (int i = 1; i < values.size() - 1; i++) {
List<Integer> copy = new ArrayList<Integer>(values);
copy.remove(i);
int val = smallestSum(copy) + values.get(i - 1) * values.get(i) * values.get(i + 1);
if (val < ret) ret = val;
}
return ret;
}
}
但是,这种解决方案仅适用于小N但不适用于更大数量的数字.我正在寻找的是使用迭代动态编程方法来实现这一目标的方法.
解决方法:
DP所需的最佳子结构是,给定去除的最后一个元素的身份,左侧元素的消除策略独立于右侧元素的消除策略.这是一个新的递归函数(smallestSumA,与问题中的版本以及比较两者的测试工具)结合了这个观察结果:
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class Foo {
public static void main(String[] args) {
Random r = new Random();
for (int i = 0; i < 10000; i++) {
List<Integer> values = new ArrayList<Integer>();
for (int n = 3 + r.nextInt(8); n > 0; n--) {
values.add(r.nextInt(100));
}
int a = smallestSumA(values, 0, values.size() - 1);
int q = smallestSumQ(values);
if (q != a) {
System.err.println("oops");
System.err.println(q);
System.err.println(a);
System.err.println(values);
}
}
}
public static int smallestSumA(List<Integer> values, int first, int last) {
if (first + 2 > last)
return 0;
int ret = Integer.MAX_VALUE;
for (int i = first + 1; i <= last - 1; i++) {
int val = (smallestSumA(values, first, i)
+ values.get(first) * values.get(i) * values.get(last) + smallestSumA(values, i, last));
if (val < ret)
ret = val;
}
return ret;
}
public static int smallestSumQ(List<Integer> values) {
if (values.size() == 3)
return values.get(0) * values.get(1) * values.get(2);
else {
int ret = Integer.MAX_VALUE;
for (int i = 1; i < values.size() - 1; i++) {
List<Integer> copy = new ArrayList<Integer>(values);
copy.remove(i);
int val = smallestSumQ(copy) + values.get(i - 1) * values.get(i) * values.get(i + 1);
if (val < ret)
ret = val;
}
return ret;
}
}
}
调用minimumSum(values,0,values.size() – 1).
要获得DP,请注意只有N为第一个和最后一个选择2个不同的设置,并记忆.运行时间为O(N ^ 3).
标签:java,algorithm,combinatorics,dynamic-programming 来源: https://codeday.me/bug/20190627/1308699.html