动态规划

Leetcode之动态规划(DP)专题-64. 最小路径和(Minimum Path Sum)

匿名 (未验证) 提交于 2019-12-02 23:57:01
Leetcode之动态规划(DP)专题-64. 最小路径和(Minimum Path Sum) m n 说明:每次只能向下或者向右移动一步。 示例: 找从左上角0,0到右下角的最短路径。DP:我们每个点(x,y)都可以表示为dp[x][y] = max( grid[x][y] + dp[x-1][y],grid[x][y] + dp[x][y-1] )第一行和第一列需要特殊处理(因为第一行上面没有数,第一列左边没有数) class Solution { public int minPathSum(int[][] grid) { int dp[][] = new int[grid.length][grid[0].length]; dp[0][0] = grid[0][0]; for(int i=1;i<grid.length;i++){ dp[i][0] = dp[i-1][0]+grid[i][0]; } for(int i=1;i<grid[0].length;i++){ dp[0][i] = dp[0][i-1]+grid[0][i]; } for(int i=1;i<grid.length;i++){ for(int j=1;j<grid[0].length;j++){ dp[i][j] = Math.min(dp[i-1][j]+grid[i][j],dp[i][j-1]

Leetcode之动态规划(DP)专题-877. 石子游戏(Stone Game)

匿名 (未验证) 提交于 2019-12-02 23:57:01
Leetcode之动态规划(DP)专题-877. 石子游戏(Stone Game) piles[i] 游戏以谁手中的石子最多来决出胜负。石子的总数是奇数,所以没有平局。 亚历克斯和李轮流进行,亚历克斯先开始。 每回合,玩家从行的开始或结束处取走整堆石头。 这种情况一直持续到没有更多的石子堆为止,此时手中石子最多的玩家获胜。 true false 示例: 输入:[5,3,4,5] 输出:true 解释: 亚历克斯先开始,只能拿前 5 颗或后 5 颗石子 。 假设他取了前 5 颗,这一行就变成了 [3,4,5] 。 如果李拿走前 3 颗,那么剩下的是 [4,5],亚历克斯拿走后 5 颗赢得 10 分。 如果李拿走后 5 颗,那么剩下的是 [3,4],亚历克斯拿走后 4 颗赢得 9 分。 这表明,取前 5 颗石子对亚历克斯来说是一个胜利的举动,所以我们返回 true 。 提示: 2 <= piles.length <= 500 piles.length 1 <= piles[i] <= 500 sum(piles) 数学题,但我们用DP来求解这一题。 我们首先定义一个类,名为P: private static class P { int fir, sec; P(int fir, int sec) { this.fir = fir; this.sec = sec; } } P中有两个属性

【动态规划】正则表达式匹配

匿名 (未验证) 提交于 2019-12-02 23:55:01
【题目链接】: https://www.acwing.com/problem/content/28/ 【题目解释】 请实现一个函数用来匹配包括 '.' 和 '*' 的正则表达式。 模式中的字符 '.' 表示任意一个字符,而 '*' 表示它前面的字符可以出现任意次(含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。 例如,字符串 "aaa" 与模式 "a.a" 和 "ab*ac*a" 匹配,但是与 "aa.a" 和 "ab*a" 均不匹配。 样例 输入: s="aa" p="a*" 输出:true 【参考】y总的视频讲解。 分3种情况来讨论问题,f[i][j] 以i为结尾的s串是否匹配以j为结尾的p串。 具体可以看代码: 1 /* 2 s="aa" 3 p="a*" 4 5 f[i][j] 指的是: s[i,...] p[j,...] 相匹配 6 7 1. 当p[i] 是正常的字符 , s[i] == p[j] , f[i][j] = f[i+1][j+1] 8 2. 当p[i] = '.' , f[i][j] = f[i+1][j+1] 9 3. 当p[i+1] = '*' ,f[i][j] = f[i][j+2] || f[i+1][j] 10 11 12 边界问题 : f[n][m] = true; 13 */ 14 15 16 17 class Solution {

【动态规划】采药

匿名 (未验证) 提交于 2019-12-02 23:49:02
原题传送门 ˼· 设dp[i][j]为前i个物体装入容量为j的背包的最大价值,w[i],v[i]分别为第i个物品的重量和价格。 那么dp[n][W]即为所求。(n为个数,W为容量)。 分两种情况: 不装入,那么dp[i][j]就等于dp[i-1][j]。 装入,那么dp[i][j]就等于dp[i-1][j-w[i]]+v[i]。 若容量j<w[i],则无法装,只能选择情况1。 否则取两种情况中价值最大者。 故状态转移方程为: dp[i][j]=dp[i-1][j] (j<w[i]) dp[i][j]=max{dp[i-1][j],dp[i-1][j-w[i]]+v[i]} (j≥w[i]) 剩下的就是小菜一碟 的Code了。 Code //经典背包,无需解释 #include<iostream> #include<cstdio> #include<cmath> using namespace std; int T,M,w[101],v[101],dp[101][1001]; int main() { //初始化 for(int i=1;i<=M;i++) { dp[i][0]=0; } for(int i=1;i<=T;i++) { dp[0][i]=0; } //读入 scanf("%d%d",&T,&M); for(int i=1;i<=M;i++) { scanf("%d%d

DP总结

匿名 (未验证) 提交于 2019-12-02 23:49:02
tags: DP 笔记 学长疯狂拉进度,先挂到这里,以后慢慢补充。。。 澶х翰 \(DP\) 设计思路 //OK 三要素 三条件 解题步骤 几种常见 \(DP\) 类型 线性 \(DP\) 区间 \(DP\) 环形 \(DP\) 简单背包 \(01\) 背包 完全背包 多重背包 混合背包 基础图论与 \(DP\) 树形 \(DP\) 基环树 \(DP\) 简单的 \(DP\) 优化 决策单调性 斜率优化 背包问题拓展 多维费用 分组背包 物品依赖 泛化物品 期望 \(DP\) 概念 期望的线性性质 期望 \(DP\) ״ѹ \(DP\) 位运算 状态压缩 什么是 \(DP\) ? 动态规划算法( \(DP,Dynamic\) \(programming\) ),它针对满足某一条件的一类问题,对各 ״̬ 维度进行 分阶段、有顺序、无重复、决策性 地转移求解。 能干什么? 动态规划通过把复杂问题分解为相对简单的子问题的方式来求解原问题。 动态规划三要素 分别是 ״̬ 、 决策 、 阶段 。 动态规划三条件 分别是 子问题重叠 、 无后效性 、 最优子结构 。 解题步骤 确定问题的研究对象,即确定 ״̬ 。 划分 阶段 ,确定 阶段 之间的状态转移方程。 考察此问题现在可否用 动态规划 来解决: 考察此问题是否具有 最优子结构 。 考察此问题是否为 无后效性 。 如果发现此问题目前不能用

动态规划合集(二)

匿名 (未验证) 提交于 2019-12-02 23:48:02
防卫导弹 //程序名:新的C++程序 //作者: #include<iostream> #include<fstream> #include<algorithm> using namespace std; int a[4005],p,dp[4005],ans; int main() { while(cin>>a[++p]); p--; for(int i=p;i>=1;i--) { for(int j=i+1;j<=p;j++)if(a[j]<=a[i])dp[i]=max(dp[i],dp[j]); dp[i]++; } for(int i=1;i<=p;i++)ans=max(ans,dp[i]); cout<<ans; return 0; } View Code 会议厅 #include<iostream> #include<algorithm> using namespace std; int n,ans; int dp[10005]; struct talk { int start,end; }a[10005]; bool cmp(talk x,talk y) { if(x.end==y.end)return x.start<y.start; return x.end<y.end; } int main() { cin>>n; for(int i=1;i<=n;i++

基础动态规划

匿名 (未验证) 提交于 2019-12-02 23:48:02
为了保证这些计算能够按顺序、不重复地进行,动态规划要求已经求解的子问题不受后续阶段的影响。这个条件也被叫做“无后效性”。换言之,动态规划对状态空间的遍历构成张有向无环图(DAG), 遍历顺序就是该有向无环图的一个拓扑序。 有向无环图中的节点对应问题中的“状态”,图中的边则对应状态之间的“转移”,转移的选取就是动态规划中的“决策”。 “状态”“阶段”和“决策”是构成动态规划算法的三要素,而“子问题重叠性”“无后效性”和“最优子结构性质”是问题能用动态规划求解的三个基本条件。动态规划算法把相同的计算过程作用于各阶段的同类子问题,就好像把个固定的公式在格式相同的若干输入数据上运行。因此,我们一般只需要定 义出DP的计算过程,就可以编程实现了。这个计算过程就被称为“状态转移方程”。 线性DP

CF 848E(动态规划+分治NTT)

匿名 (未验证) 提交于 2019-12-02 23:47:01
http://codeforces.com/problemset/problem/848/E 假设0-n一定有一条边,我们得到了一个方案,那么显然是可以旋转得到其他方案的。 记最大的i满足i到i+n有一条边,那么旋转的方案数是n-i 考虑动态规划: 设 \(g[i]\) 表示i个点,只用相邻或隔一个去拼接的方案数。 转移显然有 \(g[i]=g[i-2]+g[i-4]\) 。 设 \(f[i][0/1][0/1]\) 表示1有连对面的,n+1有连对面的,2-n填,前面后面是否要伸出去的方案数。 那么显然有 \(f[i][j][k]=g[i-1-j-k]*(i-1)^2\) 。 设 \(h[i][0/1]\) 表示前i个确定了,第i个是连对面,后面是否伸出去。 显然有 \(h[i][v]=\sum_{j=0}^{i-1}h[j][u]*f[i-j][u][v]\) 初值为: \(h[0][0]=1->ans+=?*h[?][0]\) \(h[0][1]=1->ans+=?*h[?][1]\) 由于最后一段有长度的额外贡献,所以: \(Ans=\sum_{i=0}^{n-1}h[i][u]*f[n-i][u][?]*(n-i)\) 这个东西显然可以分治NTT优化转移。 Code: #include<bits/stdc++.h> #define fo(i, x, y) for(int i

j - 分组(动态规划)

匿名 (未验证) 提交于 2019-12-02 23:43:01
链接: https://ac.nowcoder.com/acm/contest/918/J 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言65536K 64bit IO Format: %lld 题目描述 在Farmer John最喜欢的节日里,他想要给他的朋友们赠送一些礼物。由于他并不擅长包装礼物,他想要获得他的奶牛们的帮助。你可能能够想到,奶牛们本身也不是很擅长包装礼物,而Farmer John即将得到这一教训。 Farmer John的N头奶牛(1≤N≤10^4)排成一行,方便起见依次编号为1…N。奶牛i的包装礼物的技能水平为si。她们的技能水平可能参差不齐,所以FJ决定把她的奶牛们分成小组。每一组可以包含任意不超过K头的连续的奶牛(1≤K≤10^3),并且一头奶牛不能属于多于一个小组。由于奶牛们会互相学习,这一组中每一头奶牛的技能水平会变成这一组中水平最高的奶牛的技能水平。 请帮助FJ求出,在他合理地安排分组的情况下,可以达到的技能水平之和的最大值。 输入描述: 输入的第一行包含N和K。以下N行按照N头奶牛的排列顺序依次给出她们的技能水平。技能水平是一个不超过10^5的正整数。 输出描述: 输出FJ通过将连续的奶牛进行分组可以达到的最大技能水平和。 示例1 输入 复制 7 3 1 15 7 9 2 5 10 输出 复制