动态规划刷题 红太狼 2023-07-18 06:58 64阅读 0赞 # 分金子(360公司2017春招真题) # ### 题目链接 ### https://exercise.acmcoder.com/online/online\_judge\_ques?ques\_id=3863&konwledgeId=42 可以去链接里看一看,不再赘述题目了。 ### 解题思路 ### 假设几个变量,f(i,j)是从\[i,j\]中可以拿到的最大价值,因为只可以从两端拿,假如先手是从最左端拿的,那剩下的最大价值就是f(i+1,j),也就是后手能拿到的最大价值;那先手能拿到的最大价值可以用sum(i,j)-f(i+1,j)来表示。 假如先手是从最右端拿的,剩下最大价值就是f(i,j-1),也就是后手能拿到的最大价值;那先手能拿到的最大价值可以用sum(i,j)-f(i,j-1)来表示。 那究竟应该从哪边拿,当然是看f(i+1,j)和f(i,j-1)的大小,最后可以提炼出 f(i,j) = max{(sum(i,j)-f(i+1,j)),sum(i,j)-f(i,j-1)} = sum(i,j)-min{f(i+1,j),f(i,j-1)} ### 代码实现 ### #### 递归版 #### 从上式可以看出,递归是一种解决方案,为了避免重复计算,使用一个变量来记录算出来的f(n,m)的值。 def digui(lst,i,j): if(i==j): return lst[i] elif(res[i][j]!=0): return res[i][j] else: res[i][j]=sum(lst[i:j+1])-min(digui(lst,i+1,j),digui(lst,i,j-1)) return res[i][j] n=int(input()) for q in range(n): num=int(input()) res = [[0]*(num+1) for i in range(num+1)] lst=list(map(int,input().split())) lst=[0]+lst a=digui(lst,1,num) b=sum(lst)-digui(lst,1,num) print("Case #%s: %s %s"%(q+1,a,b)) #### 动态规划版 #### 我也说不上来什么叫做动态规划,总之大家都是这样叫的,当初看别人代码时,也是一脸懵比,然后自己整个手推了一遍,豁然开朗。 我们使用给的案例 4 7 2 9 5 2 上面是一列金子,先画一张表,为了方便表示,我们从1开始,0列0行都当作是空白 <table> <thead> <tr> <th>‘’</th> <th>0</th> <th>1</th> <th>2</th> <th>3</th> <th>4</th> <th>5</th> <th>6</th> </tr> </thead> <tbody> <tr> <td>0</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> </tr> <tr> <td>1</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> </tr> <tr> <td>2</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> </tr> <tr> <td>3</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> </tr> <tr> <td>4</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> </tr> <tr> <td>5</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> </tr> <tr> <td>6</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> </tr> </tbody> </table> 接下来可以填表了,假如是从\[1,1\]取,那就一种取法,就是该位置上的数量,其他只有一个金子的情形也是这样,填表。 <table> <thead> <tr> <th>‘’</th> <th>0</th> <th>1</th> <th>2</th> <th>3</th> <th>4</th> <th>5</th> <th>6</th> </tr> </thead> <tbody> <tr> <td>0</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> </tr> <tr> <td>1</td> <td>‘’</td> <td>4</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> </tr> <tr> <td>2</td> <td>‘’</td> <td>‘’</td> <td>7</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> </tr> <tr> <td>3</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>2</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> </tr> <tr> <td>4</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>9</td> <td>‘’</td> <td>‘’</td> </tr> <tr> <td>5</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>5</td> <td>‘’</td> </tr> <tr> <td>6</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>2</td> </tr> </tbody> </table> 那如果是\[1,2\]该怎么取呢,公式交给我们,应该是先得到\[1,2\]的和,然后减去较小的那个,那\[2,3\],\[3,4\]也是类似。 <table> <thead> <tr> <th>‘’</th> <th>0</th> <th>1</th> <th>2</th> <th>3</th> <th>4</th> <th>5</th> <th>6</th> </tr> </thead> <tbody> <tr> <td>0</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> </tr> <tr> <td>1</td> <td>‘’</td> <td>4</td> <td>7</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> </tr> <tr> <td>2</td> <td>‘’</td> <td>‘’</td> <td>7</td> <td>7</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> </tr> <tr> <td>3</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>2</td> <td>9</td> <td>‘’</td> <td>‘’</td> </tr> <tr> <td>4</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>9</td> <td>9</td> <td>‘’</td> </tr> <tr> <td>5</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>5</td> <td>5</td> </tr> <tr> <td>6</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>2</td> </tr> </tbody> </table> 规律很明显了,接着填表即可,最后表的状态如下。 <table> <thead> <tr> <th>‘’</th> <th>0</th> <th>1</th> <th>2</th> <th>3</th> <th>4</th> <th>5</th> <th>6</th> </tr> </thead> <tbody> <tr> <td>0</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> </tr> <tr> <td>1</td> <td>‘’</td> <td>4</td> <td>7</td> <td>6</td> <td>16</td> <td>11</td> <td>18</td> </tr> <tr> <td>2</td> <td>‘’</td> <td>‘’</td> <td>7</td> <td>7</td> <td>11</td> <td>16</td> <td>24</td> </tr> <tr> <td>3</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>2</td> <td>9</td> <td>7</td> <td>11</td> </tr> <tr> <td>4</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>9</td> <td>9</td> <td>11</td> </tr> <tr> <td>5</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>5</td> <td>5</td> </tr> <tr> <td>6</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>‘’</td> <td>2</td> </tr> </tbody> </table> 那\[1,6\]最大的收益就是1行6列的18了,后面只需要交给计算机来帮我们填表即可。 n=int(input()) for q in range(n): num=int(input()) lst = list(map(int,input().split())) res = [[0]*(num+1) for i in range(num+1)] for i in range(1,num+1): res[i][i] = lst[i-1] cnt=1 while cnt<=num: i=1 j=i+cnt while j<=num: res[i][j] = sum(lst[i-1:j]) - min(res[i][j-1],res[i+1][j]) i+=1 j+=1 cnt+=1 a = res[1][num] b = sum(lst) - a print("Case #%s: %s %s"%(q+1,a,b)) 欢迎关注公众号,一起进步 ![公众号二维码.jpg][.jpg] [.jpg]: /images/20230528/4245df545a5a4f0a89dcf613030d9f36.png
相关 LeetCode 刷题之动态规划【Python版】 1. 斐波那契数列 [509. 斐波那契数][509.] 斐波那契数 (通常用 F(n) 表示)形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面 爱被打了一巴掌/ 2024年03月27日 17:10/ 0 赞/ 103 阅读
相关 Leetcode 专项刷题题解---- 动态规划 Leetcode 专项刷题题解---- 动态规划 递归和动态规划都是将原问题拆成多个子问题然后求解,他们之间最本质的区别是,动态规划 保存了子问题的解,避免重复计算。 绝地灬酷狼/ 2024年03月26日 22:07/ 0 赞/ 132 阅读
相关 LeetCode刷题笔记-动态规划-day6 文章目录 LeetCode刷题笔记-动态规划-day6 152. 乘积最大子数组 1.题目 2.解题思路 我会带着你远行/ 2023年10月01日 18:12/ 0 赞/ 36 阅读
相关 LeetCode刷题笔记-动态规划-day5 文章目录 LeetCode刷题笔记-动态规划-day5 53. 最大子数组和 1.题目 2.解题思路 £神魔★判官ぃ/ 2023年10月01日 17:55/ 0 赞/ 24 阅读
相关 LeetCode刷题笔记-动态规划-day3 文章目录 LeetCode刷题笔记-动态规划-day3 198. 打家劫舍 1.题目 2.解题思路 布满荆棘的人生/ 2023年10月01日 17:30/ 0 赞/ 37 阅读
相关 LeetCode刷题笔记-动态规划-day2 文章目录 LeetCode刷题笔记-动态规划-day2 70. 爬楼梯 1.题目 2.解题思路 小咪咪/ 2023年10月01日 17:19/ 0 赞/ 28 阅读
相关 动态规划刷题 分金子(360公司2017春招真题) 题目链接 https://exercise.acmcoder.com/online/online\_judge\_ques?q 红太狼/ 2023年07月18日 06:58/ 0 赞/ 65 阅读
相关 力扣刷题:动态规划篇 目录 10. 正则表达式匹配 题目介绍 题目实现 32. 最长有效括号 题目介绍 题目实现 322. r囧r小猫/ 2022年10月16日 09:40/ 0 赞/ 287 阅读
相关 动态规划刷题总结 题目1: 输出描述: 对于每组数据,输出一个整数,代表最长递增子序列的长度(不需要连续)。 输入例子: 2 7 89 256 7 逃离我推掉我的手/ 2022年09月24日 15:28/ 0 赞/ 235 阅读
相关 刷题:递归问题与动态规划 include<iostream> include<vector> using namespace std; / 灰太狼/ 2021年12月19日 01:47/ 0 赞/ 270 阅读
还没有评论,来说两句吧...