19.暴力递归到动态规划(一)
This commit is contained in:
parent
04ef0490bd
commit
1448357858
|
@ -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]);
|
||||
}
|
||||
}
|
|
@ -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 |
Loading…
Reference in New Issue