输出包括两行,第一行一个整数n,代表数组arr长度,第二行包含n个整数,第i个代表arr[i]
。
输出一个整数,代表最后获胜者的分数。
4 1 2 100 4
101
时间复杂度,空间复杂度
import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int n = Integer.parseInt(br.readLine()); String[] strCards = br.readLine().split(" "); int[] cards = new int[n]; for(int i = 0; i < n; i++) cards[i] = Integer.parseInt(strCards[i]); System.out.println(first(cards, 0, cards.length - 1)); // 假设A玩家先,并让他获胜 } // 先手函数 private static int first(int[] cards, int left, int right) { if(left == right) return cards[left]; // 剩最后一张牌,拿走 // 先手利益最大化 return Math.max(cards[left] + second(cards, left + 1, right), cards[right] + second(cards, left, right - 1)); } // 后手函数 private static int second(int[] cards, int left, int right) { if(left == right) return 0; // 剩最后一张牌,被先手的拿了 return Math.min(first(cards, left + 1, right), first(cards, left, right - 1)); // 先手留最少的给后手 } }然后根据递归的依赖关系改出动规版本:(1)有两个递归函数,就有两张动态规划表;(2)对于区间[left,right]上面的结果,dp[left][right]依赖left+1和right-1,因此left从大往小遍历,right从小往大遍历;(3)left不能大于right,因此动态规划表中left>right的区域无效。
import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int n = Integer.parseInt(br.readLine()); String[] strCards = br.readLine().split(" "); int[] cards = new int[n]; for(int i = 0; i < n; i++) cards[i] = Integer.parseInt(strCards[i]); // 先手和后手一起动规 int[][] dpFirst = new int[n][n]; int[][] dpSecond = new int[n][n]; for(int right = 0; right < n; right ++){ for(int left = right; left >= 0; left --){ if(left == right){ // 只剩一张牌,先手的拿 dpFirst[left][right] = cards[left]; dpSecond[left][right] = 0; }else if(left < right){ dpFirst[left][right] = Math.max(cards[left] + dpSecond[left + 1][right], cards[right] + dpSecond[left][right - 1]); dpSecond[left][right] = Math.min(dpFirst[left + 1][right], dpFirst[left][right - 1]); } } } System.out.println(Math.max(dpFirst[0][n - 1], dpSecond[0][n - 1])); } }
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int[] arr = new int[n]; for (int i = 0; i < n; i++) { arr[i] = sc.nextInt(); } int[][] dpf = new int[n][n]; int[][] dps = new int[n][n]; for (int j = 0; j < n; j++) { for (int i = n - 1; i >= 0; i--) { if (i > j) { continue; } else if (i == j) { dpf[i][j] = arr[i]; dps[i][j] = 0; } else { dpf[i][j] = Math.max(arr[i] + dps[i + 1][j], arr[j] + dps[i][j - 1]); dps[i][j] = Math.min(dpf[i + 1][j], dpf[i][j - 1]); } } } int res = Math.max(dpf[0][n - 1], dps[0][n - 1]); System.out.println(res); } }
import java.util.Scanner; public class Main{ public static void main(String[] args){ Scanner sc=new Scanner(System.in); int n=sc.nextInt(); int[] arr=new int[n]; for(int i=0;i<n;i++){ arr[i]=sc.nextInt(); } System.out.print(win(n,arr)); } public static int win(int n,int[] arr){ if(arr==null||n==0){ return 0; } int[][] f=new int[n][n]; int[][] s=new int[n][n]; for(int j=0;j<n;j++){ f[j][j]=arr[j]; for(int i=j-1;i>=0;i--){ f[i][j]=Math.max(arr[i]+s[i+1][j],arr[j]+s[i][j-1]); s[i][j]=Math.min(f[i+1][j],f[i][j-1]); } } return Math.max(f[0][n-1],s[0][n-1]); } }
import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int[] a = new int[n]; for (int i = 0; i < n; i++) { a[i] = sc.nextInt(); } int[][] f = new int[n][n]; int[][] s = new int[n][n]; for (int i = 0; i < n; i++) { f[i][i] = a[i]; s[i][i] = 0; } for (int d = 1; d < n; d++) { for (int i = 0; i < n - d; i++) { f[i][i + d] = Math.max(a[i] + s[i + 1][i + d], a[i + d] + s[i][i + d - 1]); s[i][i + d] = Math.min(f[i + 1][i + d], f[i][i + d -1]); } } System.out.println(Math.max(f[0][n-1], s[0][n-1])); } }