ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

2022-2-5动态规划day9

2022-02-05 10:02:02  阅读:181  来源: 互联网

标签:fir day9 int Alice grid 2022 sec 动态 dp


题1:

877. 石子游戏

Alice 和 Bob 用几堆石子在做游戏。一共有偶数堆石子,排成一行;每堆都有 正 整数颗石子,数目为 piles[i] 。

游戏以谁手中的石子最多来决出胜负。石子的 总数 是 奇数 ,所以没有平局。

Alice 和 Bob 轮流进行,Alice 先开始 。 每回合,玩家从行的 开始 或 结束 处取走整堆石头。 这种情况一直持续到没有更多的石子堆为止,此时手中 石子最多 的玩家 获胜 。

假设 Alice 和 Bob 都发挥出最佳水平,当 Alice 赢得比赛时返回 true ,当 Bob 赢得比赛时返回 false 。

 

示例 1:

输入:piles = [5,3,4,5]
输出:true
解释:
Alice 先开始,只能拿前 5 颗或后 5 颗石子 。
假设他取了前 5 颗,这一行就变成了 [3,4,5] 。
如果 Bob 拿走前 3 颗,那么剩下的是 [4,5],Alice 拿走后 5 颗赢得 10 分。
如果 Bob 拿走后 5 颗,那么剩下的是 [3,4],Alice 拿走后 4 颗赢得 9 分。
这表明,取前 5 颗石子对 Alice 来说是一个胜利的举动,所以返回 true 。

示例 2:

输入:piles = [3,7,2,3]
输出:true

 

提示:

  • 2 <= piles.length <= 500
  • piles.length 是 偶数
  • 1 <= piles[i] <= 500
  • sum(piles[i]) 是 奇数
 1 class Solution {
 2     public boolean stoneGame(int[] piles) {
 3         int n=piles.length;
 4         Result[][] dp=new Result[n][n];
 5         //区间dp
 6         //dp[i][j]表示i~j石堆的结果,fir是先手最大,sec是后手最大
 7         for (int i=0;i<n;i++){
 8             for (int j=i;j<n;j++){
 9                 dp[i][j]=new Result(0,0);
10             }
11         }
12         //边界条件
13         for (int i=0;i<n;i++) {
14             dp[i][i].fir=piles[i];
15             dp[i][i].sec=0;
16         }
17         // 斜着 倒着遍历
18         for (int i=n-2;i>=0;i--) {
19             for (int j=i+1;j<n;j++) {
20                 // 先手选择左边和右边的结果
21                 int left=dp[i+1][j].sec+piles[i];
22                 int right=dp[i][j-1].sec+piles[j];
23                 if (left>right) {
24                     dp[i][j].fir=left;
25                     dp[i][j].sec=dp[i+1][j].fir;
26                 }else {
27                     dp[i][j].fir=right;
28                     dp[i][j].sec=dp[i][j-1].fir;
29                 }
30             }
31         }
32         return dp[0][n-1].fir>dp[0][n-1].sec;
33     }
34 }
35 
36 class Result{
37     int fir;
38     int sec;
39     //fir表示先手
40     //sec表示后手
41     Result(int fir,int sec){
42         this.fir=fir;
43         this.sec=sec;
44     }
45 }

思路:通用动态规划思路如注释。

题2:

64. 最小路径和

给定一个包含非负整数的 m x n 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。

说明:每次只能向下或者向右移动一步。

 

示例 1:

输入:grid = [[1,3,1],[1,5,1],[4,2,1]]
输出:7
解释:因为路径 1→3→1→1→1 的总和最小。

示例 2:

输入:grid = [[1,2,3],[4,5,6]]
输出:12

 

提示:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 200
  • 0 <= grid[i][j] <= 100
 1 class Solution {
 2     public int minPathSum(int[][] grid) {
 3         int m=grid.length,n=grid[0].length;
 4         int[][] dp=new int[m+1][n+1];
 5         for (int i=0;i<=m;i++) Arrays.fill(dp[i],Integer.MAX_VALUE);
 6         dp[0][1]=0;
 7         dp[1][0]=0;
 8         for (int i=1;i<=m;i++) {
 9             for (int j=1;j<=n;j++) {
10                 dp[i][j]=Math.min(dp[i-1][j],dp[i][j-1])+grid[i-1][j-1];
11             }
12         }
13         return dp[m][n];
14     }
15 }

思路:dp[i][j]表示到达i-1,j-1坐标的最小值。为了防止数组越界,多开一行一列数组。边界条件,要让dp[1][1] 为grid[0][0], 让dp[1][0]或者dp[0][1]一个取0,其余初始值取最大值。

标签:fir,day9,int,Alice,grid,2022,sec,动态,dp
来源: https://www.cnblogs.com/benbicao/p/15863872.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有