我有一个Point
的数组。我需要从中选择一个点子集,这样点的x坐标之和=点的y坐标之和。
如果存在许多这样的子集,则需要具有最大x坐标总和的子集。
需要报告x坐标的总和。
我写了一个强力递归方法,它测试所有可能性。
Point[] a = new Point[n];
// ...
private int rec(int i, int x, int y) {
if (i == n - 1) {
if (x + a[i].x == y + a[i].y) return x + a[i].x;
return (x == y) ? x : -1;
}
return Math.max(rec(i + 1, x, y), rec(i + 1, x + a[i].x, y + a[i].y));
}
答案是rec(0, 0, 0)
。
我的问题是:
1)是否有针对此的动态编程解决方案?
2)如果是,可以请任何人解释
答案 0 :(得分:4)
我有一点好(比蛮力)算法。
1: {(x,y): x>y}, 2: {(x,y):x==y}, 3:{(x,y): x lower-than y}
2
必须始终包含在解决方案中。1
定义net=x-y
的每个(x,y)和每个(x,y)形式3
定义net=y-x
net
中的1
和net
中的3
检索所有可能的值。有意义吗?
答案 1 :(得分:4)
对于每个点,将其值设置为x - y
。
现在我们需要找到一组其值总和为0的点。
它是NP-complete(即,对于问题的一般情况,没有已知的多项式时间算法),但是存在伪多项式时间DP解决方案,其在Wikpedia上给出,在上面链接。简要总结:
我们将函数
的值(Q(i,s)
定义为true
或false
)there is a nonempty subset of x1, ..., xi which sums to s
然后我们有以下重复:
Q(1,s) := (x1 == s) Q(i,s) := Q(i − 1, s) or (xi == s) or Q(i − 1, s − xi) for A ≤ s ≤ B
答案 2 :(得分:2)
除非有未说明的约束,否则问题是NP-Hard通过Subset-Sum的多项式时间减少,NP-Complete问题。
Subset-Sum的一种决策形式在给定一组整数X和整数s的情况下,将任何非空子集求和为s。
对于X的每个元素,构造一个Point,其x值是元素,其y值为零。构造一个额外的Point,其x值为0,其y值为s。
如果应用于该组点的等和问题的结果为0或-1,则拒绝子集求和问题。如果结果是s,则接受subset-sum。
假设P!= NP,或者至少我们没有任何NP-Hard问题的多项式算法,则没有已知的多项式时间算法来解决你的问题。
答案 3 :(得分:1)
只是尝试在java中编写代码,我觉得有用:
所有我的 ,diffOfCoordinates[i] = Xi - Yi
list
将获得最高分。
public void fun(int[] diffOfCoordinates, int indexA, int[] b, int indexB, int sum, List<Integer> list){
if(indexA == diffOfCoordinates.length){
if(sum==0){
if(list.size()<indexB){
list.clear();
for(int i=0;i<indexB;i++){
list.add(b[i]);
}
}
}
return;
}
b[indexB] = diffOfCoordinates[indexA];
fun(diffOfCoordinates, indexA+1, b, indexB+1, sum+diffOfCoordinates[indexA], list);
fun(diffOfCoordinates, indexA+1, b, indexB, sum, list);
}