这是力扣的一条题目:

 

 

  不太会的可以自己去看题解,里边讲的很详细。

  我这里主要写下我自己从递归一直优化到动态规划(空间优化)的历程。(代码可以通过力扣的oj)

递归:

 1 class Solution {
 2 public:
 3     int dfs(vector<int>&nums,int left,int right)
 4     {//这里dfs的意义是当前操作的玩家分数与另一个玩家的分数之差
 5         if(left == right)
 6             return nums[left];
 7         return max(nums[left] - dfs(nums,left+1,right),nums[right]-dfs(nums,left,right-1));
 8     }//由于"玩家的玩法都会使他的分数最大化,所以当前玩家尽量选择自己比对方分数高的策略
 9     bool PredictTheWinner(vector<int>& nums) {
10             return dfs(nums,0,nums.size()-1) >=0;//自己的分数与对方的分数之差不小于0.则自己的分数不小于对方的分数
11     }
12 };

时间效率很低,于是进行升级:

记忆化递归:

 1 class Solution {
 2 public:
 3     int memory[20][20];//既然数据范围已经给定了那么直接定义数组大小
 4     int dfs(vector<int>&nums,int left,int right)
 5     {//这里dfs的意义是当前操作的玩家分数与另一个玩家的分数之差
 6         if(memory[left][right]!=-1)
 7             return memory[left][right];
 8         if(left == right)
 9             {
10             memory[left][right]=nums[left];
11             return nums[left];
12             }
13         int ans =  max(nums[left] - dfs(nums,left+1,right),nums[right]-dfs(nums,left,right-1));
14         memory[left][right] = ans;
15         return ans;
16     }//由于"玩家的玩法都会使他的分数最大化,所以当前玩家尽量选择自己比对方分数高的策略
17     bool PredictTheWinner(vector<int>& nums) {
18             memset(memory,-1,sizeof(memory));
19             return dfs(nums,0,nums.size()-1) >=0;//自己的分数与对方的分数之差不小于0.则自己的分数不小于对方的分数
20     }
21 };

效率大大提高

然后通过总结递归的递推公式,不难联想到用动态规划代替递归:

动态规划:

 1 class Solution {
 2 public:
 3     int dp[20][20];
 4     bool PredictTheWinner(vector<int>& nums) {
 5         for(int i = 0;i<nums.size();++i)
 6         {
 7             dp[i][i] = nums[i];//初始化
 8         }
 9         for(int step = 1;step<nums.size();++step)
10         {
11             for(int i = 0;i+step<nums.size();++i)
12             {
13                 int j = i + step;
14                 dp[i][j]=max(nums[i]-dp[i+1][j],nums[j]-dp[i][j-1]); //建议结合表格理解
15             }
16         }
17         return dp[0][nums.size()-1] >=0;
18     }
19 };

虽然原理相同,但是递归便于理解,动态规划代码优雅。

其实动态规划的代码还可以更加优雅!通过优化,dp数组可以减少至一维,进一步减少内存需求。

动态规划(空间优化版):

 1 class Solution {
 2 public:
 3     int dp[20];
 4     bool PredictTheWinner(vector<int>& nums) {
 5         for(int i = 0;i<nums.size();++i)
 6         {
 7             dp[i]= nums[i];//初始化
 8         }
 9         for(int step = 1;step<nums.size();++step)
10         {
11             for(int i = 0;i+step<nums.size();++i)
12             {
13                 int j = i + step;
14                 dp[i]=max(nums[j]-dp[i],nums[i]-dp[i+1]); //建议结合表格理解
15             }
16         }
17         return dp[0] >=0;
18     }
19 };

这下代码就非常之nice

 

 


 

总结:

  在一般思路的基础上不断精进。