dp

SOSdp

匿名 (未验证) 提交于 2019-12-03 00:13:02
layout: post title: SOSdp author: "luowentaoaa" catalog: true tags: mathjax: true - codeforces - DP i = 0 pre = 0000 nex = 0001 i = 0 pre = 0010 nex = 0011 i = 0 pre = 0100 nex = 0101 i = 0 pre = 0110 nex = 0111 i = 0 pre = 1000 nex = 1001 i = 0 pre = 1010 nex = 1011 i = 0 pre = 1100 nex = 1101 i = 0 pre = 1110 nex = 1111 i = 1 pre = 0000 nex = 0010 i = 1 pre = 0001 nex = 0011 i = 1 pre = 0100 nex = 0110 i = 1 pre = 0101 nex = 0111 i = 1 pre = 1000 nex = 1010 i = 1 pre = 1001 nex = 1011 i = 1 pre = 1100 nex = 1110 i = 1 pre = 1101 nex = 1111 i = 2 pre = 0000 nex = 0100 i = 2 pre = 0001 nex =

面试常见代码题目

匿名 (未验证) 提交于 2019-12-03 00:00:02
最长公共子序列 public int lcs ( String s1 , String s2 ) { int len1 = s1 . length (); int len2 = s2 . length (); int [][] dp = new int [ len1 + 1 ][ len2 + 1 ]; for ( int i = 1 ; i <= len1 ; i ++) { for ( int j = 1 ; j <= len2 ; j ++) { if ( s1 . charAt ( i - 1 ) == s2 . charAt ( j - 1 )) { dp [ i ][ j ] = dp [ i - 1 ][ j - 1 ] + 1 ; } else { dp [ i ][ j ] = Math . max ( dp [ i - 1 ][ j ], dp [ i ][ j - 1 ]); } } } return dp [ len1 ][ len2 ]; } 可参考: https://blog.csdn.net/qq_31881469/article/details/77892324 最长公共子串 public int lcs1 ( String s1 , String s2 ) { int len1 = s1 . length (); int len2 = s2 .

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中有两个属性

Acesrc and Travel(HDU6662+换根dp)

匿名 (未验证) 提交于 2019-12-02 23:55:01
传送门 两个绝顶聪明的人在树上玩博弈,规则是轮流选择下一个要到达的点,每达到一个点时,先手和后手分别获得 \(a_i,b_i\) (到达这个点时两个人都会获得)的权值,已经经过的点无法再次经过,直到无法移动则结束游戏,两人都想最大化自己的权值和减对手权值和,问先手减后手权值和最大是多少。 ˼· 换根 \(DP\) ,和求树的直径有点类似。 \(dp[i][j]\) 表示在 \(i\) 这个结点状态为 \(j\) 时先手权值和减后手权值和最优是多少, \(j\) 为偶数表示当前是先手,为奇数时为后手。 转移方程:我们该 \(dp\) 是倒着推的,也就是说从游戏结束开始往游戏开始推,假设当前是先手选择,那么下一步就是后手移动,按照题目要求后手一定是想最小化先手减后手权值和,因此当前一定是从最小的先手减后手权值和转移过来;如果当前是后手那么就从先手减后手权值和最大转移过来。 需要特别注意的两点是: 从子结点转移过来很好想,就是子结点中相反状态转移过来,也就是当前为先手那么从最小过来;从父亲结点转移过来的时候,因为一个结点只有一个父亲结点,因此如果当前是先手,那么父亲结点也就确定了,因此它要从父亲结点从其他结点转移过来的最大值转移到当前结点,后手同理(因为这里我卡了好久,好菜啊)。 最后枚举答案的时候如果当前点是叶子结点,那么它的答案是从父亲结点贡献的,不能由它自己贡献

dp(01背包问题)

匿名 (未验证) 提交于 2019-12-02 23:49:02
且说上一周的故事里,小Hi和小Ho费劲心思终于拿到了茫茫多的奖券!而现在,终于到了小Ho领取奖励的时刻了! 小Ho现在手上有M张奖券,而奖品区有N件奖品,分别标号为1到N,其中第i件奖品需要need(i)张奖券进行兑换,同时也只能兑换一次,为了使得辛苦得到的奖券不白白浪费,小Ho给每件奖品都评了分,其中第i件奖品的评分值为value(i),表示他对这件奖品的喜好值。现在他想知道,凭借他手上的这些奖券,可以换到哪些奖品,使得这些奖品的喜好值之和能够最大。 提示一:合理抽象问题、定义状态是动态规划最关键的一步 提示二:说过了减少时间消耗,我们再来看看如何减少空间消耗 Input 每个测试点(输入文件)有且仅有一组测试数据。 每组测试数据的第一行为两个正整数N和M,表示奖品的个数,以及小Ho手中的奖券数。 接下来的n行描述每一行描述一个奖品,其中第i行为两个整数need(i)和value(i),意义如前文所述。 测试数据保证 对于100%的数据,N的值不超过500,M的值不超过10^5 对于100%的数据,need(i)不超过2*10^5, value(i)不超过10^3 Sample Input 5 1000 144 990 487 436 210 673 567 58 1056 897 Sample Output 2099 Output 对于每组测试数据,输出一个整数Ans

花园【SCOI2017期望DP入门题】

匿名 (未验证) 提交于 2019-12-02 23:48:02
小 A 的花园的长和宽分别是 L,H 。小 A 喜欢在花园里做游戏。每次做游戏的时候,他都先把花园均匀分割成 L×H 个小方块,每个方块的长和宽都是 1 。然后,小 A 会从花园的西北角的小方块出发,按照一定的规则移动,在到达花园东南角的小方块时结束游戏。每次行动时,他都会移动到当前所在的小方块的东面或南面相邻的小方块上。如果小 A 当前在从北向南数第 i 块,从西向东数第 j 块小方块上,他向东移动的概率是 Pij ,向南移动的概率则是 1-Pij 。 在花园里做游戏常常会弄脏衣服,花园的每个小方块内都有一定的不干净度,用 Dij 表示。而一次游戏结束后,小 A 总的不干净度就是他经过的所有格子中不干净度之和(起点和终点的不干净度也计算在内)。 小 B 因为小 A 经常把衣服弄脏感到苦恼,他可能会决定在小 A 做游戏前对花园进行一次打扫。小 B 在打扫花园时,会从花园的西北角的小方块出发,每次移动到当前所在的小方块的东面或南面相邻的小方块上,在到达花园的东南角时结束打扫,他经过的所有的格子的不干净度都会变为 0 。现在,小 B 想知道,在他选择了最优的打扫策略的情况下,小 A 做完游戏后总不干净度之和是多少? 第一行输入两个空格隔开的正整数 L、H。 第二行一个整数 k,值为 0 或 1 ,k=0 表示小B不会打扫花园,k=1 表示小B会在游戏开始前打扫花园。 接下来 L 行

不要62

匿名 (未验证) 提交于 2019-12-02 23:47:01
杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer)。 杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就可以消除个别的士司机和乘客的心理障碍,更安全地服务大众。 不吉利的数字为所有含有4或62的号码。例如: 62315 73418 88914 都属于不吉利号码。但是,61152虽然含有6和2,但不是62连号,所以不属于不吉利数字之列。 你的任务是,对于每次给出的一个牌照区间号,推断出交管局今次又要实际上给多少辆新的士车上牌照了。 Input输入的都是整数对n、m(0<n≤m<1000000),如果遇到都是0的整数对,则输入结束。 Output对于每个整数对,输出一个不含有不吉利数字的统计个数,该数值占一行位置。 Sample Input 1 100 0 0 Sample Output 80数位dp有板子嘿嘿,照着这个板子打就行了,所有数位dp大多可以套板子,关键是找出状态哈哈,对了,数位dp能训练记忆化搜索怎么写 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int dp[20][2]; int a[20]; int dfs(int pos,int pre,int sta

洛谷 P1044 栈

匿名 (未验证) 提交于 2019-12-02 23:47:01
有图,转 链接 这是一道卡特兰数 具体推导过程: 设dp[i]为有i个数时的方案数。设x为最后出栈的一个元素,则已经出栈的元素中比x大的元素个数为n-x个,比x小的元素个数为x-1个。那么每部分的方案数分别为dp[n - x]、dp[x - 1]。因为它们两部分互相影响,是一个乘法原理。那么当i=n时,dp[n] = ?因为x可以在1到n中取值,所以总的方案数dp[n] = dp[0] * dp[n - 1] + dp[1] * dp[n - 2] + ... + dp[n - 1] * dp[0] #include <iostream> #include <cstdio> using namespace std; int n; int f[20]; int main() { cin >> n; f[0] = f[1] = 1; for(int i = 2; i <= n; i++) for(int j = 0; j < i; j++) f[i] += f[j] * f[i - j - 1]; cout << f[n]; return 0; }

leetcode518

匿名 (未验证) 提交于 2019-12-02 23:40:02
1 class Solution { 2 public int change(int amount, int[] coins) { 3 if (amount == 0) { 4 return 1; 5 } 6 if(coins == null || coins.length == 0){ 7 return 0; 8 } 9 int[] dp = new int[amount + 1]; 10 dp[0] = 1; 11 for (int coin : coins) { 12 for (int i = coin; i <= amount; i++) { 13 dp[i] += dp[i - coin]; 14 } 15 } 16 return dp[amount]; 17 } 18 } 对比 leetcode322 : 1 public class Solution { 2 public int coinChange(int[] coins, int amount) { 3 if (amount == 0) return 0; 4 int[] dp = new int[amount + 1]; 5 dp[0] = 0; 6 for (int i = 1;i <= amount ;i++ ) { 7 dp[i] = Integer.MAX_VALUE; 8 for(int k

【题解】SDOI2010地精部落

匿名 (未验证) 提交于 2019-12-02 23:38:02
设 \(dp(i,j)\) 表示一个: 长度为 \(i\) 的 合法的 排列的第一个数字是 \(j\) 的 钦定这个排列前面两个是 递减 的 排列的方案数。 你可能会问排列前面两个递增的情况怎么办?实际上这个的方案数就是 \(dp(i,i-j+1)\) 。 转移: \(dp(i,j)=dp(i,j-1)+dp(i-1,i-j)\) 代码先鸽一下,这道题想了太久了,写代码写不清楚。