Java 如何使用回溯搜索解决问题?

Java 如何使用回溯搜索解决问题?,java,algorithm,recursion,backtracking,Java,Algorithm,Recursion,Backtracking,N人(N){ 计数++; 返回; } 对于(int j=0;jarr.length-右侧){ int约束=arr.length-i; if(arr[i]>=conditions[conditions.length-constraint]){ 返回false; } } 否则{ if(arr[i]>arr[left-1]| | arr[i]>arr[arr.length-right-1]){ 返回false; } } 返回true; } } UPD: 更改了代码,现在一切正常(但对于n=13,需要

N人(N){ 计数++; 返回; } 对于(int j=0;j=conditions[conditions.length-constraint]){ 返回false; } } 否则,如果(i>arr.length-右侧){ int约束=arr.length-i; if(arr[i]>=conditions[conditions.length-constraint]){ 返回false; } } 否则{ if(arr[i]>arr[left-1]| | arr[i]>arr[arr.length-right-1]){ 返回false; } } 返回true; } } UPD: 更改了代码,现在一切正常(但对于n=13,需要花费很多时间):

公共类回溯{
私有静态int n;
私有静态int左;
私权;
静态int-arr[];
静态int为[];
静态整数计数=0;
公共静态void main(字符串[]args)引发FileNotFoundException{
长启动=System.currentTimeMillis();
Scanner Scanner=新扫描仪(新文件(“data/File.txt”);
int inputs=scanner.nextInt();
对于(int i=0;in-1){
计数++;
返回;
}
对于(int j=0;j=conditions[conditions.length-constraint]){
返回false;
}
}
*/
如果(i==n-1){
if(countLeft(i)!=left | | countRight(i)!=right)返回false;
}
返回true;
}
私有静态int countLeft(int n){
整数计数=0;
对于(int i=0;i=0;i--){
布尔标志=假;
对于(int j=arr.length-1;j>i;j--){
if(arr[i]
即使您观察到了由于最高的人的位置而产生的快捷方式,回溯解决方案仍然会遇到太多的可能性。难怪要花太长时间。组合思考

  • 固定最高的人的位置(应该在
    P
    N-R
    之间)
  • 请注意,对于左侧分区中的任何人,右侧的视图都被阻挡。右分区也是如此。这个问题自然会以两种单向的方式分解问题
  • 还要注意,到底谁在左分区中并不重要。不管怎样,都有相同数量的排列。右分区也是如此
现在,如果最高的人在位置
k
,则有
(n-1)选择(k-1)
方法填充左侧分区。假设单向查看问题允许
F(p,k)
解决方案,那么主要问题的答案是

sum[k: P..N-R] chose(n-1,k-1) F(P-1, k-1) * F(N-k-1, n-k)
要计算
F(p,k)
,请遵循同一行。固定最高者的位置
j
(它应该在
p-1
k
之间)。有
(k-1)选择了(p-1)
填充左侧分区的方式(同样,选择谁并不重要);正确的分区可以是任意顺序。子问题的答案由递归给出

F(p, k) = sum[j: p-1..k] chose(j-1,k-1] (k-j)! F(p-1, j-1)

现在,一个简单的回忆录应该在合理的时间内给出结果。

即使你观察到了由于最高的人的位置而产生的快捷方式,回溯解决方案仍然会遇到太多的可能性。难怪要花太长时间。组合思考

  • 固定最高的人的位置(应该在
    P
    N-R
    之间)
  • 请注意,对于左侧分区中的任何人,右侧的视图都被阻挡。右分区也是如此。问题自然分解为两个单向问题
  • 还要注意,到底谁在左分区中并不重要。不管怎样,都有相同数量的排列。右分区也是如此
现在,如果最高的人在位置
k
,则有
(n-1)选择(k-1)
方法填充左侧分区。假设单向查看问题允许
F(p,k)
解决方案,那么主要问题的答案是

sum[k: P..N-R] chose(n-1,k-1) F(P-1, k-1) * F(N-k-1, n-k)
要计算
F(p,k)
,请遵循同一行。固定最高者的位置
j
(它应该在
p-1
k
之间)。有
(k-1)选择了(p-1)
填充左侧分区的方式(同样,选择谁并不重要);正确的分区可以是任意顺序。子问题的答案
F(p, k) = sum[j: p-1..k] chose(j-1,k-1] (k-j)! F(p-1, j-1)