动态规划一

61 阅读3分钟

题目一:

image.png

package class18;

public class RobotWalk2 {
    public static int process(int n,int m,int k,int p){
        if (k==0){
            return m==p?1:0;
        }
        if (m==0){
            return process(n,1,k-1,p);
        }
        if (m==n){
            return process(n,n-1,k-1,p);
        }
        return process(n,m-1,k-1,p)+process(n,m+1,k-1,p);
    }
    public static int processBag(int n,int m,int k,int p){
       int[][] bag= new int[n+1][k+1];
        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <=k; j++) {
                bag[i][j]=-1;
            }
        }
        return process2(n,m,k,p,bag);

    }

    public static int process2(int n,int m,int k,int p,int[][] bag){
        if (bag[m][k]!=-1){
            return bag[m][k];
        }
        int ans=0;
        if (k==0){
            ans= m==p?1:0;
        }else if (m==0){
            ans=process2(n,2,k-1,p,bag);
        }else if (m==n){
            ans= process2(n,n-1,k-1,p,bag);
        }else {
            ans= process2(n,m-1,k-1,p,bag)+process2(n,m+1,k-1,p,bag);
        }
        bag[m][k]=ans;
        return ans;
    }

    public static int process3(int n,int m,int k,int p){
        int[][] bag= new int[n+1][k+1];
        bag[p][0] = 1;

        for (int i = 1; i <=k; i++) {
            bag[1][i]=bag[2][i-1];
            for (int j = 2; j <n; j++) {
                bag[j][i]=bag[j-1][i-1]+bag[j+1][i-1];
            }
            bag[n][i]=bag[n-1][i-1];
        }
        return bag[m][k];

    }

    public static void main(String[] args) {
      System.out.println(process(6, 5, 2, 3));
      System.out.println(processBag(5, 2, 6, 4));
      System.out.println(process3(5, 2, 6, 4));
    }
}

题目二:

image.png

package class18;

public class Code02_CardsInLine {

   // 根据规则,返回获胜者的分数
   public static int win1(int[] arr) {
      if (arr == null || arr.length == 0) {
         return 0;
      }
      int first = f1(arr, 0, arr.length - 1);
      int second = g1(arr, 0, arr.length - 1);
      return Math.max(first, second);
   }

   // arr[L..R],先手获得的最好分数返回
   public static int f1(int[] arr, int L, int R) {
      if (L == R) {
         return arr[L];
      }
      int p1 = arr[L] + g1(arr, L + 1, R);
      int p2 = arr[R] + g1(arar, L, R - 1);
      return Math.max(p1, p2);
   }

   // // arr[L..R],后手获得的最好分数返回
   public static int g1(int[] arr, int L, int R) {
      if (L == R) {
         return 0;
      }
      int p1 = f1(arr, L + 1, R); // 对手拿走了L位置的数
      int p2 = f1(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 N = arr.length;
      int[][] fmap = new int[N][N];
      int[][] gmap = new int[N][N];
      for (int i = 0; i < N; i++) {
         for (int j = 0; j < N; 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);
   }

   // arr[L..R],先手获得的最好分数返回
   public static int f2(int[] arr, int L, int R, int[][] fmap, int[][] gmap) {
      if (fmap[L][R] != -1) {
         return fmap[L][R];
      }
      int ans = 0;
      if (L == R) {
         ans = 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);
         ans = Math.max(p1, p2);
      }
      fmap[L][R] = ans;
      return ans;
   }

   // // arr[L..R],后手获得的最好分数返回
   public static int g2(int[] arr, int L, int R, int[][] fmap, int[][] gmap) {
      if (gmap[L][R] != -1) {
         return gmap[L][R];
      }
      int ans = 0;
      if (L != R) {
         int p1 = f2(arr, L + 1, R, fmap, gmap); // 对手拿走了L位置的数
         int p2 = f2(arr, L, R - 1, fmap, gmap); // 对手拿走了R位置的数
         ans = Math.min(p1, p2);
      }
      gmap[L][R] = ans;
      return ans;
   }

   public static int win3(int[] arr) {
      if (arr == null || arr.length == 0) {
         return 0;
      }
      int N = arr.length;
      int[][] fmap = new int[N][N];
      int[][] gmap = new int[N][N];
      for (int i = 0; i < N; i++) {
         fmap[i][i] = arr[i];
      }
      for (int startCol = 1; startCol < N; startCol++) {
         int L = 0;
         int R = startCol;
         while (R < N) {
            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][N - 1], gmap[0][N - 1]);
   }

   public static void main(String[] args) {
      int[] arr = { 5, 7, 4, 5, 8, 1, 6, 0, 3, 4, 6, 1, 7 };
      System.out.println(win1(arr));
      System.out.println(win2(arr));
      System.out.println(win3(arr));

   }

}