19.暴力递归到动态规划(一)

This commit is contained in:
huayu 2022-06-24 09:41:13 +08:00
parent 04ef0490bd
commit 1448357858
3 changed files with 122 additions and 1 deletions

View File

@ -0,0 +1,115 @@
package com.learn.learn.tixi.nineteenth;
/*
给定一个整型数组arr代表数值不同的纸牌排成一条线玩家A和玩家B依次拿走每张纸牌
规定玩家A先拿玩家B后拿但是每个玩家每次只能拿走最左边或者最右边的纸牌玩家A和玩家B都绝顶聪明
请返回最后获胜者的分数[50,100,20,10]
*/
public class Code03 {
public static void main(String[] args) {
int [] arra = {5,7,4,5,8,1,6,0,3,4,6,1,7};
System.out.println(win1(arra));
System.out.println(win2(arra));
System.out.println(win3(arra));
}
// ====================================================暴力递归======================================================
public static int win1(int[] arr){
if (arr==null||arr.length==0){
return 0;
}
int first = f(arr,0,arr.length-1);
int second = g(arr,0,arr.length-1);
return Math.max(first,second);
}
public static int f(int[] arr,int l,int r){
if (l==r){
return arr[l];
}
int p1 = arr[l]+g(arr,l+1,r);
int p2 = arr[r]+g(arr,l,r-1);
return Math.max(p1,p2);
}
public static int g(int[] arr ,int l,int r){
if (l==r){
return 0;
}
int p1= f(arr,l+1,r);// 对手拿走了L位置的数
int p2= f(arr,l,r-1);// 对手拿走了R位置的数
return Math.min(p1,p2);
}
// ====================================================添加缓存======================================================
public static int win2(int[] arr){
if (arr==null||arr.length==0){
return 0;
}
int size = arr.length;
int[][] fmap = new int[size][size];
int[][] gmap = new int[size][size];
for (int i = 0;i<size;i++){
for (int j = 0;j<size;j++){
fmap[i][j]=-1;
gmap[i][j]=-1;
}
}
int first = f2(arr,0,arr.length-1,fmap,gmap);
int second = g2(arr,0,arr.length-1,fmap,gmap);
return Math.max(first,second);
}
public static int f2(int[] arr,int l,int r,int[][] fmap,int[][] gmap){
if (fmap[l][r]!=-1){
return fmap[l][r];
}
int result = 0;
if (l==r){
result= arr[l];
}else {
int p1 = arr[l]+g2(arr,l+1,r,fmap,gmap);
int p2 = arr[r]+g2(arr,l,r-1,fmap,gmap);
result= Math.max(p1,p2);
}
fmap[l][r]=result;
return result;
}
public static int g2(int[] arr ,int l,int r,int[][] fmap,int[][] gmap){
if (gmap[l][r]!=-1){
return gmap[l][r];
}
int result = 0;
if (l!=r){
int p1= f2(arr,l+1,r,fmap,gmap);
int p2= f2(arr,l,r-1,fmap,gmap);
result = Math.min(p1,p2);
}
gmap[l][r]=result;
return result;
}
// ====================================================动态规划严格表依赖======================================================
public static int win3(int[] arr){
if (arr==null||arr.length==0){
return 0;
}
int size = arr.length;
int[][] fmap = new int[size][size];
int[][] gmap = new int[size][size];
for (int i = 0;i<size;i++){
fmap[i][i]=arr[i];
}
for (int startCol = 1;startCol<size;startCol++){
int l = 0;
int r = startCol;
while (r<size){
fmap[l][r] = Math.max(arr[l]+gmap[l+1][r],arr[r]+gmap[l][r-1]);
gmap[l][r] = Math.min(fmap[l+1][r],fmap[l][r-1]);
l++;
r++;
}
}
return Math.max(fmap[0][size-1],gmap[0][size-1]);
}
}

View File

@ -1,3 +1,9 @@
记忆化搜索 记忆化搜索
尝试策略,状态转移 尝试策略,状态转移
1:28
自然智慧
### 问题1
给定一个整型数组arr代表数值不同的纸牌排成一条线玩家A和玩家B依次拿走每张纸牌规定玩家A先拿玩家B后拿但是每个玩家每次只能拿走最左边或者最右边的纸牌玩家A和玩家B都绝顶聪明请返回最后获胜者的分数。[50,100,20,10]

Binary file not shown.

After

Width:  |  Height:  |  Size: 768 KiB