http://www.cstutoringcenter.com/problems/problems.php?id=103
不想点的人,基本上就是说有个垫脚石,“-”和士兵“#”,士兵只能向右移动。如果士兵在另一个士兵后面,他必须等待士兵先移动。结束条件是所有士兵都到达终点。
2 名士兵在 5 个垫脚石上移动的方式数。
1) ##--- #-#-- -##-- -#-#- --##- --#-# ---##
2) ##--- #-#-- -##-- -#-#- -#--# --#-# ---##
3) ##--- #-#-- #--#- -#-#- --##- --#-# ---##
4) ##--- #-#-- #--#- -#-#- -#--# --#-# ---##
5) ##--- #-#-- #--#- #---# -#--# --#-# ---##
我使用广度优先搜索,有 5 个石头,它在几秒钟内运行,但有 10 个石头,它需要几个小时,时间随着深度呈指数增长。我该如何处理?
我的代码:
状态.java
import java.util.ArrayList;
public class State {
public int stones;
public Soldiers[] soldiers;
public String currentState ="";
public boolean visited = false;
public State(int stones,int Numsoldiers){
System.out.println(Numsoldiers);
this.stones = stones;
soldiers = new Soldiers[Numsoldiers];
System.out.println("length" + soldiers.length);
initState();
}
public State(int stones,Soldiers[] soldiers){
this.stones = stones;
this.soldiers = soldiers;
paintState();
}
public void initState(){
for(int i=0;i<soldiers.length;i++)
{
soldiers[i] = new Soldiers();
soldiers[i].position =i;
currentState+="#";
}
for(int j=soldiers.length;j<stones;j++)
{
currentState+="-";
}
}
private void paintState(){
for(int j=0;j<stones;j++)
{
currentState+="-";
}
char[] stateChar = currentState.toCharArray();
currentState = "";
for(int i=0;i<soldiers.length;i++){
stateChar[soldiers[i].position] = '#';
}
for(int k=0; k<stateChar.length;k++){
currentState += stateChar[k];
}
}
public void printState(){
System.out.println(currentState);
}
public ArrayList<State> getNextStates(){
ArrayList<State> States = new ArrayList<State>();
for(int i=0;i<soldiers.length;i++){
Soldiers[] newSoldiers = new Soldiers[soldiers.length];
for(int j=0;j<soldiers.length;j++){
newSoldiers[j] = new Soldiers(soldiers[j].position);
}
if(!((newSoldiers[i].position+1)==stones))
{
if((currentState.charAt((newSoldiers[i].position+1))=='-'))
{
newSoldiers[i].move();
States.add(new State(stones,newSoldiers));
}
}
}
if(States.size()==0)
{
TestSoldiers.count++;
}
return States;
}
}
士兵.java
public class Soldiers {
int position = 0;
public Soldiers(){
position =0;
}
public Soldiers(int pos){
position = pos;
}
public void move(){
position ++;
}
}
TestSoldiers.java
import java.util.LinkedList;
import java.util.Queue;
public class TestSoldiers {
public static int count=0;
public static void main(String[] args){
TestSoldiers t = new TestSoldiers();
}
public TestSoldiers()
{
State s = new State(10,3);
breadthFirstTraversal(s);
System.out.println(count);
}
public void breadthFirstTraversal(State rootNode){
Queue<State> q = new LinkedList<State>();
q.add(rootNode);
while(!q.isEmpty()){
State n = (State)q.poll();
n.printState();
for(State adj : n.getNextStates()){
q.add(adj);
}
}
}
}
我怎样才能做到这一点,以便我只考虑每个状态一次,同时保持结束方式总数的完整性(在 TestSoldiers.java 中计数)?
对于那些想要修改参数的人来说,它是新的 State(n,k),其中 n 是石头的数量,k 是士兵的数量。