java - 具有动态规划问题的桶数组
问题描述
我正在使用 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,我们的目标是找到我们得分最高的最佳选择顺序。
我知道 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;
}
}
解决方案
好的,所以我在 Github 上找到了此类任务的代码,如果他们以后需要,我会将其留给其他人:
推荐阅读
- safari - Safari CORS 问题 - Access-Control-Allow-Origin 不允许主机
- javascript - Javascript 展开数组/更改数据结构
- icloud - CloudKit“部署到生产”不显示记录更改,“部署”灰显
- ruby-on-rails - 使用 STI,临时子类的第一次读取失败,但后续读取工作
- python - (1) 处的外部函数“f”在带有 f2py 的子程序中没有隐式类型
- mysql - MySQL - 使用子查询优化查询
- android - 在 Android Studio 中获取红色类且没有语法错误
- java - 使用两个 JList 将字母转换为字母位置
- swift - Swift 闭包导致强大的 self 循环
- sql - 基于星期几返回计数或空值的 Netezza SQL 语句