leetcode_Stone Game_dp_思维
Alex和Lee玩游戏,共有偶数堆石头,石头总数为奇数,两人每次要么拿第一堆,要么拿最后一堆,两人以最优策略拿石堆(一次拿走完整的一堆),Alex先手,Alex赢返回True,否则返回False。
思路:一共偶数堆石头,当石堆总数为偶数时,Alex拿;当石堆总数为奇数时,Lee拿。每次拿石堆,要么拿第一堆,要么拿最后一堆。
dp[i][j][0]:当石堆第一堆为i,最后一堆为j时,Alex取得石头的总数。
dp[i][j][1]:当石堆第一堆为i,最后一堆为j时,Lee取得石头的总数。
dp过程相当于计算两人去石头方式的所有可能。
并且,只要有一种情况下Alex能赢,那么Alex就必赢,因为两人以最优策略取石堆且Alex先手。
bool stoneGame(vector<int>& piles) { int dp[505][505][2]; int head=0,tail=piles.size()-1; memset(dp,0,sizeof(dp)); bool flag=0; for(int i=head; i<=tail; i++) for(int j=tail; j>=i; j--) { int len=j-i+1; if(len%2==0) { dp[i+1][j][0]=dp[i][j][0]+piles[i]; dp[i][j-1][0]=dp[i][j][0]+piles[j]; dp[i+1][j][1]=dp[i][j][1]; dp[i][j-1][1]=dp[i][j][1]; } else { if(i==j) { dp[i+1][j][1]=dp[i][j][1]+piles[i]; dp[i+1][j][0]=dp[i][j][0]; if(dp[i][j][0]>dp[i+1][j][1]) { printf("%d %d\n",dp[i][j][0],dp[i+1][j][1]); flag=1; } } else { dp[i+1][j][1]=dp[i][j][1]+piles[i]; dp[i][j-1][1]=dp[i][j][1]+piles[j]; dp[i+1][j][0]=dp[i][j][0]; dp[i][j-1][0]=dp[i][j][0]; } } } if(flag) return 1; else return 0; }