AcWing 170. 【Java】加成序列
原题链接
简单
作者:
tt2767
,
2019-12-28 01:16:25
,
所有人可见
,
阅读 961
// 1. dfs 顺序 每位数范围最小值是 buffer[idx-1]+1, 最大值是 min(n, 2*buffer[idx-1])
// 2. dfs 状态 深度(1~n), 当前位置(cur)
// 3. 剪枝
// 3.1 优化搜索顺序 : 先按大的搜
// 3.2 排除等效冗余 ?
// 3.3 可行性剪枝: 当前值 > n 非法
// 3.4 最优化剪枝: ?
// 3.5 记忆化 ? 增加判重
import java.util.*;
import java.util.stream.*;
public class Main{
void run(){
while (jin.hasNext()){
int n = jin.nextInt();
if (n == 0) break;
System.out.println(solve(n));
}
}
String solve(int n){
res = null;
for (int i = 1 ; i <= n ; i++){
buffer.clear();
buffer.add(1);
dfs(1, 1, i, n);
if (res != null) return res;
}
return res;
}
boolean dfs(int curDepth, int curIndex, int maxDepth, int n){
if (buffer.get(buffer.size()-1) == n) {
res = String.join(" ", buffer.stream().map(x->String.valueOf(x)).collect(Collectors.toList()));
return true;
}
if (curDepth > maxDepth) return false;
// int last = buffer.get(curIndex-1);
// for (int i = 2 * last ; i > last ; i-- ){ // 遍历多了,可能存在不是由前面的数组合相加的数
// buffer.add(i);
// if (dfs(curDepth+1, curIndex+1, maxDepth, n)) return true;
// buffer.remove(buffer.size()-1);
// }
Arrays.fill(visit, false);
for (int i = curIndex-1; i >= 0 ; i-- ){
for (int j = i; j >= 0 ; j-- ){
int next = buffer.get(i) + buffer.get(j);
if (visit[next] || next > n || next <= buffer.get(curIndex-1)) continue; // <= 注意边界
buffer.add(next);
visit[next] = true; // 忘记加也过了😂
if (dfs(curDepth+1, curIndex+1, maxDepth, n)) return true;
buffer.remove(buffer.size()-1);
}
}
return false;
}
boolean[] visit = new boolean[200];
private String res = null;
private List<Integer> buffer = new ArrayList<>();
private Scanner jin = new Scanner(System.in);
public static void main(String[] args) throws Exception {new Main().run();}
}