dfs+剪枝
注意剪枝条件:
如果还剩下2k+1个坑位, 最多有k+1个树属于同一个种类
如果还剩下2k个坑位, 最多有k个树属于同一个种类
所以剪枝条件为: 2*树i的数量 > (剩余坑位+1)
package t2; import java.util.ArrayList; import java.util.Scanner; public class Main { public static void main(String[] args) { f(); } // 存放答案的全局序列 public static ArrayList<Integer> street = new ArrayList<>(); public static void f() { Scanner sc = new Scanner(System.in); int n_cate = sc.nextInt(); int[] num_tree = new int[n_cate]; int sum = 0; for (int i = 0; i < n_cate; i++) { num_tree[i] = sc.nextInt(); sum += num_tree[i]; } boolean res = dfs(num_tree,0, sum); if(res==true){ for (Integer integ :street){ System.out.print(integ+1); System.out.print(" "); } System.out.println(); }else{ System.out.println("-"); } } // num_tree: 每种树的数量 // next_loc: 下一个要种树的位置 // len_street: 道路的长度 public static boolean dfs(int[] num_tree, int next_loc, int len_street) { // 树种满了 if(next_loc==len_street) return true; // 剪枝 for (int i1 : num_tree) { if(2*i1>(len_street-next_loc+1)) return false; } // dfs for (int i = 0; i < num_tree.length; i++) { if (next_loc == 0 || (i != street.get(next_loc-1) && num_tree[i] > 0)) { street.add(i); num_tree[i]--; boolean res = dfs(num_tree, next_loc+1, len_street); if(res==true) return true; num_tree[i]++; street.remove(street.size()-1); } } return false; } }