Я делаю задачу с динамическим программированием на Java, и я застрял: в задаче нам дан массив блоков со случайным количеством камней внутри, где оба игрока знают их количество с самого начала.Игроки берут туры и выбирают одно пограничное ведро по бокам:
Ведра: (3) (3) (8) (2) (10) (4)
P1: (3) ведраслева: (3) (8) (2) (10) (4),
P2: (4) ведра слева: (3) (8) (2) (10),
P1: (10) левых ведер: (3) (8) (2),
P2 (3) левых ведер: (8) (2),
P1: (8)ведра слева (2),
P2: (2) конец
Окончательный счет рассчитывается с (камни игрока 1) - (камни игрока2)
Счет = (3 + 10 + 8) - (4 + 3 + 2) = 12
Мы играем в player1, и наша цель - найти ОПТИМАЛЬНЫЙ порядок выбора, в котором у нас самый большой счет.
IЯ знаю концепцию DP, но я понятия не имею, что я могу сэкономить, чтобы улучшить время.Основную часть кода я сделал с помощью алгоритма minmax, и он работал, но я понятия не имею, как совместить его с динамическим программированием
Я попытался использовать матрицу со строками в виде сегментов слева и столбцов в виде сегментов справа,так что я могу сохранить там ответы, когда мы используем одну и ту же «часть» массива, но у меня были некоторые проблемы с ним ...
EDIT1: добавлен мой код
public int maxGain(int[] values)
{
this.moves = new int[values.length+1][values.length+1];
return _maxGain(values,0,values.length-1,0,0,values.length,true,0,0);
}
public int _maxGain(int[] values, int leftBowl, int rightBowl, int valuePlayer1, int valuePlayer2,int leftBowls, boolean ifFirstPlayer, int leftMoves, int rightMoves){
//Check if end of the game
if(leftBowls == 0) {
//Calculate the final score
return valuePlayer1 - valuePlayer2;
}
//System.out.println("Left:"+values[leftBowl]+", right: "+values[rightBowl]);
// If first player
if(ifFirstPlayer){
int maxEval = Integer.MIN_VALUE;
int eval;
for(int i=0;i<2;i++){
if(i==0){
//Do move
valuePlayer1 = valuePlayer1+values[leftBowl];
leftBowls--;
leftMoves++;
if(moves[leftMoves][rightMoves] != 0){
eval = moves[leftMoves][rightMoves];
System.out.println("USED! Left:"+leftMoves+",right: "+rightMoves+" Moves: " + moves[leftMoves][rightMoves] );
}else {
eval = _maxGain(values, leftBowl + 1, rightBowl, valuePlayer1, valuePlayer2, leftBowls, false, leftMoves, rightMoves);
moves[leftMoves][rightMoves] = eval;
System.out.println("Left:"+leftMoves+",right: "+rightMoves+" Moves: " + moves[leftMoves][rightMoves] );
for(int x=0;x<this.moves.length;x++){
for(int j=0;j<this.moves.length;j++){
System.out.print(this.moves[x][j]+" ");
}
System.out.println();
}
}
leftMoves--;
maxEval = Math.max(maxEval,eval);
//Undo move
valuePlayer1 = valuePlayer1-values[leftBowl];
leftBowls++;
}else{
//Do move
valuePlayer1 = valuePlayer1+values[rightBowl];
leftBowls--;
rightMoves++;
if(moves[leftMoves][rightMoves] != 0){
eval = moves[leftMoves][rightMoves];
System.out.println("USED! Left:"+leftMoves+",right: "+rightMoves+" Moves: " + moves[leftMoves][rightMoves] );
}else {
eval = _maxGain(values, leftBowl, rightBowl - 1, valuePlayer1, valuePlayer2, leftBowls, false, leftMoves, rightMoves);
moves[leftMoves][rightMoves] = eval;
System.out.println("Left:"+leftMoves+",right: "+rightMoves+" Moves: " + moves[leftMoves][rightMoves] );
for(int x=0;x<this.moves.length;x++){
for(int j=0;j<this.moves.length;j++){
System.out.print(this.moves[x][j]+" ");
}
System.out.println();
}
}
rightMoves--;
maxEval = Math.max(maxEval,eval);
//Undo move
valuePlayer1 = valuePlayer1-values[rightBowl];
leftBowls++;
}
}
return maxEval;
//If second player
}else{
int minEval = Integer.MAX_VALUE;
int eval;
for(int i=0;i<2;i++){
if(i==0){
//Do move
valuePlayer2 = valuePlayer2+values[leftBowl];
leftBowls--;
leftMoves++;
if(moves[leftMoves][rightMoves] != 0){
eval = moves[leftMoves][rightMoves];
System.out.println("USED! Left:"+leftMoves+",right: "+rightMoves+" Moves: " + moves[leftMoves][rightMoves] );
}else {
eval = _maxGain(values, leftBowl + 1, rightBowl, valuePlayer1, valuePlayer2, leftBowls, true, leftMoves, rightMoves);
moves[leftMoves][rightMoves] = eval;
System.out.println("Left:"+leftMoves+",right: "+rightMoves+" Moves: " + moves[leftMoves][rightMoves] );
for(int x=0;x<this.moves.length;x++){
for(int j=0;j<this.moves.length;j++){
System.out.print(this.moves[x][j]+" ");
}
System.out.println();
}
}
leftMoves--;
minEval = Math.min(minEval,eval);
//Undo move
valuePlayer2 = valuePlayer2-values[leftBowl];
leftBowls++;
}else{
//Do move
valuePlayer2 = valuePlayer2+values[rightBowl];
leftBowls--;
rightMoves++;
if(moves[leftMoves][rightMoves] != 0){
eval = moves[leftMoves][rightMoves];
System.out.println("USED! Left:"+leftMoves+",right: "+rightMoves+" Moves: " + moves[leftMoves][rightMoves] );
}else {
eval = _maxGain(values, leftBowl, rightBowl - 1, valuePlayer1, valuePlayer2, leftBowls, true, leftMoves, rightMoves);
moves[leftMoves][rightMoves] = eval;
System.out.println("Left:"+leftMoves+",right: "+rightMoves+" Moves: " + moves[leftMoves][rightMoves] );
for(int x=0;x<this.moves.length;x++){
for(int j=0;j<this.moves.length;j++){
System.out.print(this.moves[x][j]+" ");
}
System.out.println();
}
}
rightMoves--;
minEval = Math.min(minEval,eval);
//Undo move
valuePlayer2 = valuePlayer2-values[rightBowl];
leftBowls++;
}
}
return minEval;
}
}