dp

HDU 2571(DP 和 初始化问题)

大兔子大兔子 提交于 2019-11-26 15:55:25
设 $dp[i][j]$ 表示第 $i$ 行,第 $j$ 列的最大幸运值。 对于第 $i$ 行 $j$ 列的最大值转移状态: 1、来自于第 $i-1$ 行 $j$ 列,取$dp[i-1][j] 。$ 2、来自第 $i$ 行 $j-1$ 列,取$dp[i][j-1]。$ 3、由于他会跳步,比如我现在是第 $9$ 列,那么它会从同行第 $1$ 列跳 $k=9$ 过来;从同行第 $3$ 列 跳 $k=3$ 过来;当然原地跳不算。 故你会发现,枚举 $k$ 值,$k$ 从小于 $j$ 列的地方跳 $k$ 倍过来,面对不是 $j$ 的约数,跳过即可。 初始化问题: 此题限定了起点,即我必须从最左上角开始走,那么对于$dp[1][0]$ 和 $dp[0][1]$ 如果我设的是负无穷的话,那么对于起点$dp[i][j]$ ,我一定要选择左边的点$(dp[1][0])$和上面的点$(dp[0][1])$,而这两点都是负无穷,这样会改变 dp 的起点值,我们需要让整个状态从左上角转移,所以$dp[1][0]$ 和 $dp[0][1]$ 要设为 $0$ 。 其次,对于边界: $dp[0][i]$与$dp[i][0]$,为了保证我一定要从 上面一个点(对于$dp[i][1]$ )或从左边一个点(对于$dp[1][j]$)转移过来,故需要将这两条边界设为负无穷(除了上面所说的 $dp[1][0] 和 dp

[动态规划] leetcode 72 Edit Distance

寵の児 提交于 2019-11-26 14:32:25
problem: https://leetcode.com/problems/edit-distance/ 二维爬台阶。dp[ i ][ j ] 代表长度为i的word1和长度为j的word2的最小转换次数。dp[ i ][ j ]可以由dp[ i ][ j - 1] 或 dp[ i - 1][j - 1]加一个数得到,也可以由dp[ i - 1][ j - 1] 加上替换一个数得到(如果最后两个数字相等,就不算替换) class Solution { public: int minDistance(string word1, string word2) { int m = word1.size(); int n = word2.size(); vector<vector<int>> dp(m + 1, vector<int>(n + 1)); for(int i = 0;i <= m;i++) { dp[i][0] = i; } for(int j = 0;j <= n; j++) { dp[0][j] = j; } for(int i = 0;i < m; i++) { for(int j = 0;j < n;j++) { dp[i + 1][j + 1] = min(min(dp[i + 1][j], dp[i][j + 1]) + 1, dp[i][j] + (word1

leetcode 62. 不同路径(C++)

旧街凉风 提交于 2019-11-26 10:56:43
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。 问总共有多少条不同的路径? class Solution { public: int uniquePaths(int m, int n) { vector<int> dp(n, 1); for (int i = 1; i < m; ++i) { for (int j = 1; j < n; ++j) { dp[j] += dp[j - 1]; } } return dp[n - 1]; } }; 思路: 动态规划,类比爬梯子那道题。可以维护一个二维数组dp,其中dp[i][j]表示到当前位置不同的走法的个数,然后可以得到递推式为: dp[i][j] = dp[i - 1][j] + dp[i][j - 1],这里为了节省空间,我们使用一维数组dp,一行一行的刷新也可以 来源: https://www.cnblogs.com/xiaotongtt/p/11318342.html

leetcode 53 最大子序和

六眼飞鱼酱① 提交于 2019-11-26 00:41:34
leetcode 53 最大子序和 求任何的最大值和最小值问题时,一定要将最开始的值定义成理论上的最大值和最小值 define INT_MAX 0x7fffffff define INT_MIN 0x80000000 思路一:直接暴力法求解 利用双循环,在第二个循环里,每次计算一个和值,并且与定义的最大值比较,如果比最大值大,则将最大值置为该和值,在第一个循环里,每次将和值置为0。 class Solution { public : int maxSubArray ( vector < int > & nums ) { //暴力法求解,利用双循环,求这一类最大值最小值的问题,一定要定义成理论上的最大值和最小值 //define INT_MAX 0x7fffffff //define INT_MIN 0x80000000 int maxSum = INT_MIN ; for ( int i = 0 ; i < nums . size ( ) ; i ++ ) { int sum = 0 ; for ( int j = i ; j < nums . size ( ) ; j ++ ) { sum + = nums [ j ] ; if ( sum > maxSum ) { maxSum = sum ; } } } return maxSum ; } } ; 思路二:DP(动态规划)求解

G - 免费馅饼(dp)

大兔子大兔子 提交于 2019-11-25 19:31:13
G - 免费馅饼 都说天上不会掉馅饼,但有一天gameboy正走在回家的小径上,忽然天上掉下大把大把的馅饼。说来gameboy的人品实在是太好了,这馅饼别处都不掉,就掉落在他身旁的10米范围内。馅饼如果掉在了地上当然就不能吃了,所以gameboy马上卸下身上的背包去接。但由于小径两侧都不能站人,所以他只能在小径上接。由于gameboy平时老呆在房间里玩游戏,虽然在游戏中是个身手敏捷的高手,但在现实中运动神经特别迟钝,每秒种只有在移动不超过一米的范围内接住坠落的馅饼。现在给这条小径如图标上坐标: 为了使问题简化,假设在接下来的一段时间里,馅饼都掉落在0-10这11个位置。开始时gameboy站在5这个位置,因此在第一秒,他只能接到4,5,6这三个位置中其中一个位置上的馅饼。问gameboy最多可能接到多少个馅饼?(假设他的背包可以容纳无穷多个馅饼) Input 输入数据有多组。每组数据的第一行为以正整数n(0<n<100000),表示有n个馅饼掉在这条小径上。在结下来的n行中,每行有两个整数x,T(0<T<100000),表示在第T秒有一个馅饼掉在x点上。同一秒钟在同一点上可能掉下多个馅饼。n=0时输入结束。 Output 每一组输入数据对应一行输出。输出一个整数m,表示gameboy最多可能接到m个馅饼。 提示:本题的输入数据量比较大,建议用scanf读入,用cin可能会超时。