算法作业第三题,集合覆盖问题近似计算
例题:
Sample Input
1 2 3 4 5
4
1 2 3
2 4
3 4
4 5
Sample Output
2
1 4
只测试了样例一组,可能会存在问题,请谨慎参考
import java.util.*;
public class Main {
public static ArrayList<Integer> Uaggregate = new ArrayList<Integer>(); //存放全集
public static ArrayList<Integer> tmpAggregate = new ArrayList<Integer>(); //存放临时的集合
public static ArrayList<Integer> tmpAgNum = new ArrayList<Integer>(); //存放临时的集合是由哪几个子集组成的
public static ArrayList<Integer> BestAgNum = new ArrayList<Integer>(); //存放临时的集合是由哪几个子集组成的
public static int num;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String Str = sc.nextLine();
String[] str = Str.split(" ");
for(int i=0;i<str.length;i++) {
Uaggregate.add(Integer.parseInt(str[i])); //给全集赋值
}
int m = sc.nextInt();
sc.nextLine();
num = m;
ArrayList<Integer> subset[] = new ArrayList[m];
for(int i=0;i<m;i++) {
Str = sc.nextLine();
str = Str.split(" ");
subset[i] = new ArrayList<Integer>();
for(int j=0;j<str.length;j++) {
subset[i].add(Integer.parseInt(str[j])); //子集赋值
}
}
Recursion(subset, 0, m); //递归遍历全部可能
System.out.println(num);
//转化成标准输出格式
int[] bestAgNum = new int[BestAgNum.size()]; //存放最终最优结果的数组
for(int i=0;i<BestAgNum.size();i++) {
System.out.print((BestAgNum.get(i)+1)+" ");
}
}
static void Recursion(ArrayList<Integer> subset[], int i, int m) {
if(i<m-1) //不加当前集合
Recursion(subset, i+1, m);
ArrayList<Integer> tmp = new ArrayList<Integer>();
tmp = (ArrayList<Integer>) tmpAggregate.clone();
tmpAggregate.removeAll(subset[i]); //加当前集合
tmpAggregate.addAll(subset[i]);
tmpAgNum.add(i);
if(tmpAggregate.size()==Uaggregate.size() && tmpAgNum.size()<num) {
BestAgNum = (ArrayList<Integer>) tmpAgNum.clone();
num = tmpAgNum.size();
}
else if(tmpAgNum.size()<num && i<m-1){
Recursion(subset, i+1, m);
}
tmpAggregate = (ArrayList<Integer>) tmp.clone(); //加当前集合情况下退栈
tmpAgNum.remove(tmpAgNum.size()-1);
}
}