dp

leetcode[221]最大正方形

亡梦爱人 提交于 2020-02-13 20:55:00
题目:在一个由 0 和 1 组成的二维矩阵内,找到只包含 1 的最大正方形,并返回其面积。 示例: 输入: 1 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1 0 0 1 0 输出: 4 源码: /** * dp表示最大正方形边长,dp[i][j] = MIN(dp[i-1][j-1], dp[i][j-1], dp[i-1][j]); */ #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define MAX(a, b) ((a) > (b) ? (a) : (b)) int maximalSquare(char** matrix, int matrixSize, int* matrixColSize){ int i, j, max; int** dp = (int**)malloc(sizeof(int*) * matrixSize); for(i = 0; i < matrixSize; i++){ dp[i] = (int*)malloc(sizeof(int) * matrixColSize[0]); } max = 0; for(i = 0; i < matrixSize; i++){ for(j = 0; j < matrixColSize[0]; j++){ if(matrix[i][j] == '1'){ dp[i

算法(三十一)

一个人想着一个人 提交于 2020-02-13 13:24:01
1、给一个函数,返回 0 和 1,概率为 p 和 1-p,请你实现一个函数,使得返回 0 1 概率一样 public int random(){ int i = RANDOM(); int j = RANDOM(); int result; while (true) { if (i == 0 && j == 1) { result = 0; break; } else if (i == 1 && j == 0) { result = 1; break; } else continue; } return result; } 2、硬币1元,3元,5元,给定金额target,输出最少需要多少枚硬币 动态规划 public static int coinNum(int target) { int[] coin = {1,3,5}; int[] dp = new int[target+1]; for(int i=0;i<target+1;i++) dp[i] = i; for(int i=1;i<target+1;i++) for(int j=0;j<coin.length;j++) if(coin[j] <= i && dp[i-coin[j]]+1 < dp[i]) dp[i] = dp[i-coin[j]]+1; return dp[target]; } 3、硬币1元,3元,5元

n的m划分

六眼飞鱼酱① 提交于 2020-02-11 23:34:01
n的m划分: dp[i][j]表示j的i划分,也就是将j颗球放入i个袋子里面,最后的答案是dp[m][n] 状态转移方程为 dp[i][j]=dp[i-1][j]+dp[i][j-i]; 划分方法有两种: ①有的袋子不放球:dp[i-1][j] , 比如n=4,m=3,那么可以有2+2或者1+3或者4的方法分完四颗球 , i-1表示至少有一个袋子不放球,j表示一共有j颗球 ②所有的袋子都不为空,至少有一颗球:dp[i][j-i] , 也就是1+1+2的方法 ,i表示每个袋子都放球, j-i表示每个袋子都放上一颗球之后剩下j-i颗球 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<queue> 5 #include<map> 6 #include<vector> 7 #include<set> 8 #include<string> 9 #include<cmath> 10 #include<cstring> 11 using namespace std; 12 int n,m,M; 13 int dp[1010][1010]; 14 void solve() 15 { 16 dp[0][0]=1; 17 for(int i=0;i<=m;i++) 18 { 19 for(int j=0

算法学习:数位DP

允我心安 提交于 2020-02-11 17:09:23
【解决问题】 一个极大的多位数字中,存在某种特殊情况出现多少次 通过记忆化和动态规划的方法,将之前的情况数记录下来,在计算其他情况的时候,通过状态的转移相互利用 【模板】 【题意】求1~n之间有多少个数又含有13又能被13整除,(1<=n<=1e9) 【代码】 #include<cstdio> #include<cstring> #define MAXN 20 int dp[MAXN][MAXN][10]; int maxx[MAXN]; //maxx记录整个数字的上限 //len 表示当前枚举的数字长度 //mod 表示状态之一,现在这个长度对16取余的结果 //stu 状态之一,当前的数字是否存在 //lim 状态之一,前面的数字是否达到上限,因为枚举的情况在前面没有达到的话,后面的是可以任取的 // 而如果达到的话,就需要考虑数字的取值范围了 int Geta(int len,int mod,int stu,bool lim) { //从后往前开始枚举数字的情况 if(len==0) //当所有位置上的数字列举完成之后 return mod==0&&stu==2; //返回存在的情况 if(!lim && dp[len][mod][stu]) return dp[len][mod][stu]; //max 表示需要遍历到的最大的数字 int cnt=0,max=lim

floyd+动态规划 hdu-4571-Travel in time

╄→尐↘猪︶ㄣ 提交于 2020-02-10 11:10:49
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4571 题目大意: 有n个景点,每个点都有个游玩时间ci,游玩后得到的满意度si。给一个起点s和终点e,两个景点间有条无向边,权值为时间。从起点出发,在给定时间限制下,到达终点,问能获得的最大的满意值,只有游玩了景点才能获得该景点的满意值,并且上个游玩景点的满意度必须大于后一个游玩的景点满意度。 解题思路: 图上的dp. 见到图论就晕啊啊啊。先求出不游玩时,任意两点的到达时间,用floyd求。 dp[i][j]表示到达第i个点,用时为j时,能到达的最大的满意度。 本题的关键是先对每个景点的满意度从小到大排序,然后对于第i个景点枚举时间j(从大到小,因为一个景点只能游一次), 在枚举前面的i-1个景点,通过前面的满意度得出当前的满意度。转移方程还是很好写的。 代码: #include<iostream> #include<cmath> #include<cstdio> #include<cstdlib> #include<string> #include<cstring> #include<algorithm> #include<vector> #include<map> #include<set> #include<stack> #include<list> #include

「JSOI2013」游戏中的学问

孤者浪人 提交于 2020-02-08 16:38:36
「JSOI2013」游戏中的学问 传送门 考虑 \(\text{DP}\) 设 \(dp_{i, j}\) 表示将前 \(i\) 个人分成 \(j\) 个集合,并且第 \(i\) 个人在第 \(j\) 个集合的方案数。 转移就是: \[ dp_{i, j} = dp_{i - 1, j} \times (i - 1) + dp_{i - 3, j - 1} \times {i - 1 \choose 2} \times 2 \] 其中前面那一项就是加入一个人,感觉有点像第一类斯特林数递推式中的一部分。。。 然后后面那一项就是我们新开一个集合,强制 \(i\) 在这个集合中,然后再随便选两个人来组成一个圈,因为 \(3\) 个人的圆排列个数是 \(2\) 所以还要乘个 \(2\) 。 #include <cstdio> #define rg register #define file(x) freopen(x".in", "r", stdin), freopen(x".out", "w", stdout) template < class T > inline void read(T& s) { s = 0; int f = 0; char c = getchar(); while ('0' > c || c > '9') f |= c == '-', c = getchar();

dp--状压dp

…衆ロ難τιáo~ 提交于 2020-02-08 13:25:39
Problem Description 互不侵犯 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子。 Analysis of ideas 把每一行的每一个状态用一个二进制数表示 定义dp[i][j][k]为第i行,状态为j,已经放了k个棋子的方案数 Accepted code 来源: https://www.cnblogs.com/hezongdnf/p/12276068.html

【LeetCode 32】最长有效括号

我们两清 提交于 2020-02-08 04:23:27
题目链接 【题解】 设dp[i]表示以第i个字符结尾的最长有效括号的长度。 显然只要考虑s[i]==')'的情况 则如果s[i-1]=='(',则dp[i] = dp[i-2]+2; 如果s[i-1]==')',那么我们现在要在i前面去给s[i]==')'这个右括号去找左括号。 那么显然我们要先让s[i-1]这个右括号得到匹配。不然轮不到s[i]. 所以我们先往前走dp[i-1]长度. 然后看看i-1-dp[i-1]是不是左括号(这时才能轮得上s[i],这里面其实还要求dp[i]真的是 最长的 有效括号长度才行,不然不能直接这样判断) 是的话我们就得到一个长度为dp[i-1]+2的有效序列了。 当然别忘了前面还有dp[i-1-dp[i-1]-1]要加上去因为也可能是合法的匹配序列。 【代码】 class Solution { public: int longestValidParentheses(string s) { int dp[100000]; memset(dp,0,sizeof(dp)); int len = s.size(); int ans = 0; for (int i = 0;i < len;i++){ if (s[i]==')'){ if (i-1>=0){ if (s[i-1]=='('){ if (i-2<0) dp[i] = 2;else dp[i] =

动态规划之最长上升子序列

不羁的心 提交于 2020-02-07 06:19:25
给定一个无序的整数数组,找到其中最长上升子序列的长度。 示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。 class Solution { public: int lengthOfLIS(vector<int>& nums) { if(nums.size() == 0) return 0; vector<int> dp(nums.size()+1,1); for(int i = 0; i < nums.size(); i++){ dp[i] = 1; for(int j = 0; j < i; j++){ if(nums[j] < nums[i]){ dp[i] = max(dp[i],dp[j]+1); } } } int max1 = 0; for(int i = 0;i < dp.size();i++){ max1 = max(dp[i],max1); } return max1; } }; 1)使用vector定义不定长集合 2)使用自带的max函数 3)dp[i]表示第i个数加入dp中的结果。当第i个数加入dp中时,我们依次遍历[0,i)的所有情况。一开始,我们总是假设dp[i] = 1;然后逐步增大j的值,当出现满足条件的情况,让他进行dp[i] 的值更新。 例如: [10,9

最长的有效括号

蹲街弑〆低调 提交于 2020-02-04 19:31:52
给定一个只包含 '(' 和 ')' 的字符串,找出最长的包含有效括号的子串的长度。 示例 1: 输入: "(()" 输出: 2 解释: 最长有效括号子串为 "()" 示例 2: 输入: ")()())" 输出: 4 解释: 最长有效括号子串为 "()()"思路:动态规划,只需要考虑两个有效的连续括号,()()这种形式和((()))这种形式,前一种是dp[i]=dp[i-2]+2;后面dp=dp【i-1】+2; 注意()(())结合起来。这时dp[i] = dp[i - 1] + 2 + dp[i - 1 - dp[i - 1] - 1];综合可见下面解答。 来源: https://www.cnblogs.com/zzas0/p/10533645.html