leetcode877
这道题目的限制条件是比较trick的,它说了是偶数个数字,所以其实先手必胜。因为先手者可以计算编号是奇数的堆的和以及编号是偶数的堆的和,然后比较,如果奇数堆和大的话,那就先选择第一个,然后保持选择奇数堆即可。如果是偶数堆和较大的话,那么先选择最后一个堆,然后保持选择偶数堆即可。
但是更一般的来说,我们用动态规划来解决这个问题,用dp[i][j]表示piles[i]-piles[j]之间先手可以赢后手的分数,并且此时先手取的是i或者j。那么最后的结果就是看dp[0][n-1](n是piles的长度),因为0和n-1就是先手可以进行选择的目标。
对于某个范围dp[i][j]来说,如果先手取i,那么dp[i][j] = piles[i]-dp[i+1][j],因为piles[i+1]~piles[j]是后手赢先手的分数,所以此时先手选择piles[i]和它做差;当然先手也可以取j,那么dp[i][j] = piles[j]-dp[i][j-1]。最后就是取这两者的极大值,即 dp[i][j] = max(piles[i]-dp[i+1][j], piles[j]-dp[i][j-1])。可以看出是一个区间的DP。
1 class Solution { 2 public: 3 bool stoneGame(vector<int>& piles) { 4 int n = (int)piles.size(); 5 vector<vector<int>> dp(n+1, vector<int>(n+1, 0)); 6 for(int i=0;i<n;i++) dp[i][i] = piles[i]; 7 for(int l=1;l<n;l++){ 8 for(int i=0;i+l<n;i++){ 9 dp[i][i+l] = max(piles[i]-dp[i+1][i+l], piles[i+l]-dp[i][i+l-1]); 10 } 11 } 12 return (dp[0][n-1]>0); 13 } 14 };
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号