九章算法高级班笔记6.动态规划(下)

  1. 区间类DP
  • Stone Game
  • Burst Ballons
  • Scramble String
  1. 匹配类动规
  • Longest Common Subsequence
  • Edit Distance
  • K Edit Distance
  • Distinct Subquence
  • Interleaving String
  1. 背包类DP
  • BackPackI
  • BackPackII
  • K SUM
  • Minimum Adjustment Cost

 

区间类Dp 

cs3k.com

特点:

  1. 求一段区间的解max/min/count
  2. 转移方程通过区间更新
  3. 从大到小的更新

Coins in a Line III cs3k.com

There are n coins in a line. Two players take turns to take a coin from one of the ends of the line until there are no more coins left. The player with the larger amount of money wins.

Could you please decide the first player will win or lose?

Have you met this question in a real interview? Yes
Example
Given array A = [3,2,2], return true.

Given array A = [1,2,4], return true.

Given array A = [1,20,4], return false.

来来来, 先画个图:
Evernote Snapshot 20171105 151531 (1)

如图, 我们发现, 一下相同的重复的[2], 可以用记忆花搜索. 但是, 假设我们用一个状态dp[1], 我们不知道剩的一个, 是2, 是3还是4啊. 因为现在取一个硬币,可以从左边取, 也可以从右边取, 是有方向性的, 所以不能用dp[i]表示.
现在我们呢, 用一个区间的两个下标表示

public class Solution { /** * @param values: an array of integers * @return: a boolean which equals to true if the first player will win */ public boolean firstWillWin(int[] values) { // write your code here int n = values.length; int[] sum = new int[n + 1]; sum[0] = 0; for (int i = 1; i <= n; ++i) sum[i] = sum[i - 1] + values[i - 1]; // s[i][j] = sum[j + 1] - sum[i]; int[][] dp = new int[n][n]; for (int i = 0; i < n; ++i) dp[i][i] = values[i]; for (int len = 2; len <= n; ++len) { for (int i = 0; i < n; ++i) { int j = i + len - 1; if (j >= n) continue; int s = sum[j + 1] - sum[i]; dp[i][j] = Math.max(s - dp[i + 1][j], s - dp[i][j - 1]); } } return dp[0][n - 1] > sum[n] / 2; } } // 方法一 import java.util.*; public class Solution { /** * @param values: an array of integers * @return: a boolean which equals to true if the first player will win */ public boolean firstWillWin(int[] values) { // write your code here int n = values.length; int [][]dp = new int[n + 1][n + 1]; boolean [][]flag =new boolean[n + 1][n + 1]; int sum = 0; for(int now : values

转载于:https://www.cnblogs.com/jiuzhangsuanfa/p/9895696.html

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值