public int getWinValue(int[] arr) { int n = arr.length; int low = 0; int high = n - 1; int turn = 0; int max = 0; int sum = 0; for(int i = 0; i < n; i ++){ sum += arr[i]; } while(low <= high){ if(turn++ % 2 == 0){ max += Math.max(arr[low], arr[high]); } if(arr[low] > arr[high]){ low ++; }else{ high --; } } return Math.max(max, sum-max); }
class Solution { private: int memorized_dfs(int i, int j, vector<vector<int> > &dp, vector<int> &A) { if (i == j) return dp[i][j] = A[i]; else if (i > j) return 0; int v = max(min(A[i] + memorized_dfs(i + 2, j, dp, A), /* 先手拿左边, 后手拿剩下的左边 */ A[i] + memorized_dfs(i + 1, j - 1, dp, A)), /* 先手拿左边, 后手拿剩下的右边 */ min(A[j] + memorized_dfs(i + 1, j - 1, dp, A), /* 先手拿右边, 后手拿剩下的左边 */ A[j] + memorized_dfs(i, j - 2, dp, A))); /* 先手拿右边, 后手拿剩下的右边 */ return dp[i][j] = v; } public: /** * 得到硬币博弈问题的获胜分值 * 输入:代表硬币排列情况的数组arr * 返回:硬币博弈问题的获胜分值 */ int getWinValue(vector<int> arr, int len) { vector<vector<int> > dp(len, vector<int>(len, -1)); int sum = 0; for (int i = 0; i < arr.size(); ++i) sum += arr[i]; int first = memorized_dfs(0, len - 1, dp, arr); int second = sum - first; return max(first, second); } };
public int getWinValue(int[] arr) { if(arr.length==1)return arr[0]; int a[]=getPath(arr, 0, arr.length-1); return a[0]>a[1]?a[0]:a[1]; } //返回子节点的收益以及该节点的收益,第一个数据表示的是子节点的收益,第二个数据表示该节点的收益,使用递归的方式解决 public int[] getPath(int []arr,int first,int last){ int t[]=new int[2]; if(last==first+1){ if(arr[first]>=arr[last]){ t[0]=arr[last]; t[1]=arr[first]; } else{ t[0]=arr[first]; t[1]=arr[last]; } return t; } int a[]=new int[2]; int b[]=new int[2]; a=getPath(arr, first+1, last); b=getPath(arr, first, last-1); if(arr[first]+a[0]>=arr[last]+b[0]){ t[0]=a[1]; t[1]=arr[first]+a[0]; } else{ t[0]=b[1]; t[1]=arr[last]+b[0]; } return t; }
import java.util.ArrayList; import java.util.List; import java.util.Scanner; public class Solution { public static Scanner sc = new Scanner(System.in); public static int N; public static int array[]; public static int dpfirst[][]; public static int dpsecond[][]; public static int first(int left, int right) { // 先手 if (left == right) { return array[left]; } else { int a = second(left + 1, right) + array[left]; int b = second(left, right - 1) + array[right]; // 想要的是后手的最大的 return Math.max(a, b); } } public static int second(int left, int right) { if (left == right) { return 0; } else { int a = first(left + 1, right); int b = first(left, right - 1); // 因为自己不能选,只能对方选,因此对方一定会返回给自己更小的数 return Math.min(a, b); } } public int getWinValue(int[] arr) { array = arr; N = arr.length; dpfirst = new int[N][N]; dpsecond = new int[N][N]; for (int left = 0; left < N; left++) { for (int right = 0; right < N; right++) { dpfirst[left][right] = -1; dpsecond[left][right] = -1; } } for (int i = 0; i < N; i++) { dpfirst[i][i] = array[i]; dpsecond[i][i] = 0; } int count = 1; while(count < N){ for (int i = 0; i < N - count; i++) { int left = i; int right = i + count; int a = dpsecond[left + 1][right] + array[left]; int b = dpsecond[left][right - 1] + array[right]; dpfirst[left][right] = Math.max(a, b); dpsecond[left][right] = Math.min(dpfirst[left + 1][right], dpfirst[left][right - 1]); } count++; } return Math.max(dpfirst[0][N - 1],dpsecond[0][N - 1]); } }
class Solution { public: /** * 得到硬币博弈问题的获胜分值 * 输入:代表硬币排列情况的数组arr * 返回:硬币博弈问题的获胜分值 */ int getWinValue(vector<int> arr, int len) { vector<vector<int>> dp(len,vector<int>(len,0)); vector<int> sum(len,0); sum[0] = arr[0]; for(int i=0;i<len;i++){ dp[i][i] = arr[i]; if(i>0) sum[i] = arr[i]+sum[i-1]; } int j; for(int l=1;l<len;l++) for(int i=0;i+l<len;i++){ j = i+l; dp[i][j]=sum[j]-sum[i-1]-min(dp[i+1][j],dp[i][j-1]); } return dp[0][len-1]>sum[len-1]-dp[0][len-1]?dp[0][len-1]:sum[len-1]-dp[0][len-1]; } int min(int a,int b){ if(a>b) return b; else return a; } };dp[l,r]表示先拿者可以获得的最大分数,dp[l,r]=max((sum(l,r)-dp[l+1,r]),sum(l,r)-dp[l,r-1]),sum(l,r)表示该区间上的总分数=sum(r)-sum(l-1),初始dp[i,i]=arr[i]
public static int getWinValue(int[] arr){ int low = 0; int higth = arr.length-1; int turn=0,sum = 0,max=0; //计算总面额 for(int i=0; i<arr.length; i++){ sum += arr[i]; } while(low <= higth){ //玩家1取数 if(turn++ %2 == 0){//玩家1取的顺序是第0,2,4,6...次 max += Math.max(arr[low], arr[higth]); } //移动数组指针 if(arr[low] > arr[higth]){//说明上一步取的是arr[low] low++; } else if(arr[low] < arr[higth]){//说明上一步取的是arr[higth] higth--; } else if(arr[low] == arr[higth]){//比如arr[8,10,3,2,6,3],玩家1更乐意取左边的3而不是右边的,这样保证下下一步玩家1可取到6 if(arr[low+1] >= arr[higth-1]){ higth--; }else{ low++; } } } return Math.max(max, sum-max); }
public class Solution { public int getWinValue(int[] arr) { int fh=0, sh=0,sum=0; for(int i=0;i<arr.length;i++){ sum+=arr[i]; } fh=getFirstHandMaxValue(arr); sh=sum-fh; if(fh>=sh) return fh; else return sh; } private int getFirstHandMaxValue(int[] arr){ int fh=0; int length = arr.length; if(length==1){ fh=arr[0]; }else{ int sum1=0; int sum2=0; int[] subarr1=new int[length-1]; int[] subarr2=new int[length-1]; for(int i=0;i<length-1;i++){ subarr1[i]=arr[i+1]; subarr2[i]=arr[i]; sum2+=arr[i]; sum1+=arr[i+1]; } fh=Math.max(arr[0]+sum1-getFirstHandMaxValue(subarr1), arr[length-1]+sum2-getFirstHandMaxValue(subarr2)); } return fh; } public static void main(String[] args){ Solution s = new Solution(); int[] arr = {1,9,1,9,1}; System.out.print(s.getWinValue(arr)); } } 自己写的可是系统检测和别人的相似了
class Solution { public: /** * 得到硬币博弈问题的获胜分值 * 输入:代表硬币排列情况的数组arr * 返回:硬币博弈问题的获胜分值 */ int getWinValue(vector<int> arr, int len) { int a[len][len], //a的最高得分 b[len][len]; //b的最高得分 for(int j=0;j<len;j++){ for(int i=j;i>=0;i--){ if(i==j){ a[i][j]= arr[i]; b[i][j]=0; } else{ a[i][j]= max(arr[i]+b[i+1][j],arr[j]+b[i][j-1]); b[i][j]= arr[i]+a[i+1][j]+b[i+1][j]-a[i][j]; } } } return max(a[0][len-1], b[0][len-1]); } int max(int a, int b){ return a>b? a:b; } };
int WonerPerson(int arr[],int n)//比较函数,返回胜者的分数 { int i=0,j=n-1; int sum1=0,sum2=0;//定义甲(sum1),乙(sum2)的计数器 while(i<=j){ if(arr[i]>=arr[j]) {sum1+=arr[i];i++;} else {sum1+=arr[j];j--;} if(arr[i]>=arr[j]) {sum2+=arr[i];i++;} else {sum2+=arr[j];j--;} } return sum1>sum2?sum1:sum2; } int main (void) { int n=4; int arr[]={7,6,5,9}; int king=WonerPerson(arr,n); printf("%5d",king); system("pause"); return 0; }