我有一个带有n个整数数组的向量(我们称之为数组)和数字k。我必须找到一种制作矢量的方法,让我们称之为Sol,其属性是所有元素的总和为k而Sol [i]来自Arrays [i]。 例如:
首先是n,第二个是k,然后是数组。
输入:
3 10
1 2 3
2 5 7
4 6 8
控制台:
2 2 6
我可以简单地使用回溯,但这是一个巨大的复杂性。我尝试制作一个从底部开始的算法,对于每个点,它从下面组合点,制作可能的解决方案列表,如:
3 10
1 2 3
2 5 7
4 6 8
ex for:
8 < 10, viable solution
6 < 10, viable solution
4 < 10, viable solution
7 + 8 = 15 < 10 false never check this path again
7 + 6 = 13 < 10 false never check this path again
...
即使我这样做,也有一些复杂性很大的情况。我的目标是O(m * k)复杂度,其中m是所有输入数组的长度之和。
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Iterator;
import java.util.Scanner;
import java.util.Vector;
public class Main {
static Vector<Vector<Integer>> Arrays;
static int Arrays_lenght;
static int sum;
public static void main(String[] args) throws FileNotFoundException
{
Scanner data_in = new Scanner(new File("data.in"));
Arrays_lenght = data_in.nextInt();
sum = data_in.nextInt();
Arrays = new Vector<>();
data_in.nextLine();
//read vectors
for(int i = 0; i < numar_vectori; i++)
{
String temp = data_in.nextLine();
Scanner _temp = new Scanner(temp);
Vector<Integer> temp_vector = new Vector<>();
while (_temp.hasNext()) {
temp_vector.add(_temp.nextInt());
}
Arrays.add(temp_vector);
}
Iterator<Vector<Integer>> itr = Arrays.iterator();
while (itr.hasNext())
System.out.printf("%s\n", itr.next().toString());
}
}
这是我在java中读取输入文件的代码。如何以O(m * k)复杂度制作Sol矢量,其中m是所有输入数组的长度之和?
答案 0 :(得分:2)
动态编程解决方案(我假设输入数组A[][]
包含自然数):
创建2D数组B[][]
- N行,K + 1列,填充零。
for every element of the first input array el=A[0][ix]
set B[0][el] = ix+1
// incrementing is useful to separate filled entries from empty ones
for i = 1 to n-1
for every element of i-th input array `el=A[i][ix]`:
for every ik index in range 0..Sum-el
if B[i - 1, ik] is filled then
set B[i, ik + el] = ix+1
at the end:
if B[N-1, K] is filled
unwind indexes of elements that produce needed sum
第二阶段对输入矩阵的每个元素执行最多K次(第一个数组行除外),因此时间复杂度为O(K * M)。