![](https://img-blog.csdnimg.cn/20190918140053667.png?x-oss-process=image/resize,m_fixed,h_224,w_224)
动态规划
动态规划题目
我有一個夢想
IT
展开
-
买卖股票的最佳时机-Leetcode 121 - python
给定一个数组,它的第i个元素是一支给定股票第i天的价格。如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。注意你不能在买入股票前卖出股票。示例 1:输入: [7,1,5,3,6,4]输出: 5解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。 ...原创 2019-03-08 15:30:42 · 163 阅读 · 0 评论 -
HDU 4508(湫湫系列故事——减肥记I)基础完全背包
直接套模板的完全背包代码:#include#includeint dp[100010],a[110],b[110];int m,n;int Max(int a,int b){ return a>b?a:b;}int main(){ int i,j; while(scanf("%d",&n)!=EOF) { memset(dp原创 2015-08-07 14:28:18 · 324 阅读 · 0 评论 -
HDU 2844(Coins)多重背包
题目描述说:He wanted to pay the exact price(without change) and he known the price would not more than m.But he didn't know the exact price of the watch.就是说原创 2015-08-10 09:25:48 · 320 阅读 · 0 评论 -
HDU 1059(Dividing)多重背包
题目就是要分弹珠,一人一半,多一个少一个都不行。六种弹珠,ni表示价值i的弹珠的数量,问能不能分。1.总价值为奇数当然不能分了。2.总价值为偶数,利用多重背包求解,背包容量为m/2,计算dp[m]能否等于m,能就可以分。代码#include#includeint val[10],num[10];int dp[210010],m;int count=1;int Max(原创 2015-08-10 09:37:18 · 438 阅读 · 0 评论 -
HDU 3732(Ahui Writes Word)多重背包
这题一看就是个背包题目,01背包种类n,容量c可是n和c太大了,那样o(nc)肯定超时。其实这题的什么单词根本无所谓了,我们只关心它的c和v,而且c和v都只要c和v一样,我们就看做一种物品,数量+1,这样就转化成多重背包问题了,物品种类不超过100,利用二进制优化。代码:#include#includeint dp[10010],num[11][11],cost[110]原创 2015-08-10 15:01:06 · 386 阅读 · 0 评论 -
HDU 1421(搬寝室)动态规划
题目要求差的平方和最小,就是相邻的数相减差的平法和最小了。先排序,dp[i][j]表示第i对,第j个数时所得的最小值,动归方程:i==2j时,刚好凑成最小对数,dp[i][j]=dp[i-1][j-2]+(a[j]-a[j-1])*(a[j]-a[j-1]); i代码:#include#include#includeusing namespace std;int dp原创 2015-08-11 12:55:11 · 384 阅读 · 0 评论 -
HDU 2546(饭卡)0-1背包问题
题目就是尽量把饭卡钱用完,如果饭卡钱少于5元就不能买了。我们可以先留5块钱,用剩下的钱尽量多买(0-1背包问题,求最大容量),然后用那剩下的五块钱去买前面没有买过最贵的东西,这样就是花的最多,卡余额最少的注意开始的时候如果就少于五块钱,那就什么也买不了了代码:#include#include#include#includeusing namespace std;int原创 2015-07-03 08:14:33 · 409 阅读 · 0 评论 -
HDU 3339(In Action)最短路SPFA+0-1背包问题
题目大意就是有N个敌人站点,每个站点能量powd[i],我们要从基地派坦克去占领这些站点,占领的站点能量总和要大于总能量的一半。一个站点一辆坦克,我们要计算出最少路径,就是从基地到各个占领的站点路径总和最小。单源最短路径可以用SPFA。一个站点要不就占领要不就不占领,让人想到了背包的放与不放。impossible的情况就是那些无法到达的站点能量总和大于等于一半能量。题目目的是求原创 2015-07-06 10:59:20 · 435 阅读 · 0 评论 -
HDU 1712(ACboy needs your help)分组背包问题
第ith course最多只能选一种方案,就是每一行最多选一种,把每一行看成一组,他们相互冲突,最多选一种应该算是基础分组背包吧,套背包九讲的公式代码#include#includeint Max(int a,int b){ return a>b?a:b;}int main(){ int n,m; int i,j,k; int a[110原创 2015-08-10 10:41:03 · 349 阅读 · 0 评论 -
HDU 2079(选课时间)多重背包
多重背包求方案总数,Max改成Sum代码:#include#includeint dp[700],c[20],num[20];int m,n;int main(){ int T,i,j,k; scanf("%d",&T); while(T--) { scanf("%d%d",&m,&n); memset(c,0,原创 2015-08-10 09:52:25 · 641 阅读 · 0 评论 -
[动态规划]数塔问题
数塔问题就是从顶点向下走,每个节点有个权值,求到达底部节点时所经过节点和最大用动态规划思想,从底部自下而上求dp[i][j]=max{dp[i+1][j],dp[i+1][j+1]}+dp[i][j]。原创 2015-08-11 14:18:18 · 823 阅读 · 0 评论 -
HDU 2955(Robberies)0-1背包问题
这题看起来有点像最大报销额度,貌似要求的问题是小数。题目给的是每个银行被抓的概率,我们要转换成逃跑的概率,而且概率是乘积:(1-p1)*(1-p2)...*(1-pn),才是跑掉的概率。0-1背包问题,把概率当容量显然不行,精度不行,不像最大报销额度只要2位小数。我们把概率当价值,钱当容量,计算出抢到m钱的最大逃跑率是多少。然后从所有银行钱总量往前找,找到第一个逃跑概率满足要求的便是能抢到原创 2015-07-02 14:16:02 · 524 阅读 · 0 评论 -
HDU 1950(Bridging signals)最长不降子序列nlogn
这个题和HDU1025异曲同工,一个意思,就是求最长不降子序列。代码:#include#includeint BinSearch(int key,int* d,int left,int right){ int mid; while(left<=right) { mid=(left+right)/2; if(key>d[mid]原创 2015-06-24 08:16:18 · 764 阅读 · 0 评论 -
HDU 2602(Bone Collector)基础0-1背包问题
本题就是最简单的0-1背包问题代码:#include#includeint dp[1001][1001],v[1001],val[1001];int Max(int a,int b){ return a>b?a:b;}int main(){ int T; int i,vol,n,vi; scanf("%d",&T); while(原创 2015-07-02 09:34:18 · 342 阅读 · 0 评论 -
HDU 2151(Worm)动态规划-数塔问题
比较明显的数塔问题,只是这是求方案总数动归方程稍微变化下,把Max变成Sum,有点像背包求方案总数 dp[i][j]=dp[i+1][j-1]+dp[i+1][j+1]同样边界单独求下.代码:#include#includeint dp[110][110];int main(){ int i,j; int n,p,m,t; while(s原创 2015-08-11 14:45:55 · 539 阅读 · 0 评论 -
爬楼梯-Leetcode-python
爬楼梯假设你正在爬楼梯。需要n阶你才能到达楼顶。每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?注意:给定n是一个正整数。示例 1:输入: 2输出: 2解释: 有两种方法可以爬到楼顶。1. 1 阶 + 1 阶2. 2 阶示例 2:输入: 3输出: 3解释: 有三种方法可以爬到楼顶。1. 1 阶 + 1 阶 + 1 阶...原创 2019-03-08 14:34:34 · 202 阅读 · 0 评论 -
HDU 3336(Count the string)DP+KMP
题目要求字符串所有前缀在字符串出现的次数之和,次数包括重叠部分(例如ababa,前缀aba出现次数为2次)朴素思想,枚举前缀,各自KMP算个数,题目数据量较大,不允许这样。前后缀问题一般会想到利用NEXT数组的性质。例如abababa,NEXT:0012345,设dp[i]为第i字符为止,前缀(1~i)出现的次数,dp[i]=dp[nextp[i]]+1代码#inc原创 2015-09-01 16:12:40 · 423 阅读 · 0 评论 -
HDU 2191(悼念512汶川大地震遇难同胞——珍惜现在,感恩生活)多重背包
标准多重背包:方法1:转化为01背包代码:#include#includeint Max(int a,int b){ return a>b?a:b;}int main(){ int i,j,k,n,m; int dp[110]; int p[110],h[110],c[110]; int T; scanf("%d",&T)原创 2015-08-07 14:44:31 · 372 阅读 · 0 评论 -
HDU 3033(I love sneakers!)分组背包变形
看起来很像分组背包,就是每一组的数量至少一,和最多一个又不一样,这里初始化无穷小。这题是看了别人的题解的。状态转移方程:dp[i][j]表示进行到了第i组容量为j所装载的最大价值。则dp[i][j]这个状态必须从dp[i-1][j-w[x]]+p[x] (选了第1个第i组的物品),dp[i][j-w[x]]+p[x](已经选过第i组的物品,这次又选了第i组的物品),dp[i][j](不选这原创 2015-08-10 11:25:18 · 398 阅读 · 0 评论 -
HDU 1028(Ignatius and the Princess III)区间DP之整数划分
区间DP整数划分题,自己的区间DP比较菜,云里雾里,方程不会推。一看题就知道要打表了,n=120.当n<m时,由于分法不可能出现负数,所以record[n][m]=record[n][n];当n==m时,那么就得分析是否要分出m这一个数,如果要分那就只有一种{m},要是不分,那就是把n分成不大于m-1的若干份;即record[n][n]=1+record[n][n-1];当n>m时原创 2015-08-10 15:13:20 · 410 阅读 · 0 评论 -
[动态规划]最长公共子序列问题(LCS)
最长公共子序列是动态规划的经典问题:状态转移方程:dp[i][j] = 0 如果i=0或j=0dp[i][j] = dp[i-1][j-1] + 1 如果X[i-1] = Y[i-1]dp[i][j] = max{ dp[i-1][j], dp[i][j-1] } 如果X[i-1] != Y[i-1] 此问题网上好多文章介绍,百度即可,转移方程要记住。还有就是要记录原创 2015-08-10 13:12:59 · 474 阅读 · 0 评论 -
HDU 1171(Big Event in HDU)0-1背包问题
此题把总价值的一半作为背包容量,背包的数量要把所以数量都算上,这样就是简单的0-1背包问题了,价值作为容量和价值,求出的最大价值便是B总价值-B=A;这个的结束标识n>0.代码:#include#includeint dp[125051],val[5050]; //种类*价值*数量/2 最大125000 int Max(int a,int b){ return a>b?a原创 2015-07-02 15:36:30 · 373 阅读 · 0 评论 -
HDU 1160(FatMouse's Speed)最长不降子序列nlogn+路径记录
此题要求老鼠体重递增,速度递减的最长序列。先按照老鼠速度递减排序,如果速度相同按体重递增排序。这样速度已经满足要求,再在体重中找最长递增序列,便是题目要求的最长序列。nlogn+记录路径:路径不唯一#include#include#includeusing namespace std; typedef struct node{ int weight,speed,t原创 2015-06-24 09:02:08 · 399 阅读 · 0 评论 -
HDU 1257(最少拦截系统)最长不降子序列
此题导弹高度是递减的(包括相等)的,所以对于递增的字序列,此序列肯定不在一个导弹系统中,而其它高度的导弹必定可以和此递增序列共用一个系统。例如:100 3 999 4 5 2,(100 ,999)(3,999)(3,4,5)不能共用一个系统,此处至少得有3个系统,而100,999,2可以包括在这三个系统中如(100,3)(999,4)(5,2)三套系统。代码:nlogn#include原创 2015-06-24 08:44:01 · 292 阅读 · 0 评论 -
HDU 1025(Constructing Roads In JGShining's Kingdom)最长不降子序列nlogn
题目大意就是要求最长不降子序列,n比较大,用n*n算法肯定超时,所有采用nlogn算法。代码:#include#includeint a[500001],d[500001],n;int Binsearch(int key,int* d,int left,int right){ int mid; while(left<=right) { m原创 2015-06-24 08:07:52 · 402 阅读 · 0 评论 -
HDU 2084(数塔)动态规划-数塔问题
赤裸裸的数塔公式题,这题目的就是教你写最基本的数塔题。代码:#include#includeint dp[110][110];int Max(int a,int b){ return a>b?a:b;}int main(){ int T; int n,i,j; scanf("%d",&T); while(T--) {原创 2015-08-11 14:25:05 · 489 阅读 · 0 评论 -
HDU 1176(免费馅饼)动态规划-数塔
这题把5作为数塔的顶点,因为最多移动左右一步,也可以原地不动,这样就成了一个数塔问题了,特殊处理下节点10和节点0,还有它同一时刻同一地点可能不止掉一个,也就是说数据会重复出现方程:dp[t][i]=Max(Max(dp[t+1][i-1],dp[t+1][i+1]),dp[t+1][i])+dp[t][i]代码:#include#includeint dp[100010][原创 2015-08-11 14:37:15 · 381 阅读 · 0 评论 -
HDU 5807(Revenge of LIS II)最长不降子序列
题目大意是找第二长不降子序列,如果两个序列数字一样但是数字在原序列下标不一样也算不同序列。答案无非两种可能 1.等于最长序列长度 2.最长序列长度-1情况分析:1.第一次到达最长序列长度,再往后扫描,如果再次出现最长序列长度的,那么答案就是最长序列长度2.第一次出现最长序列的位置往前扫描,如果序列之间出现重复数字(如1 2 2 5)或者(1 4 3 5)情况,答案就是最长序列长度原创 2015-06-24 15:11:14 · 538 阅读 · 0 评论 -
HDU 1248(寒冰王座)基础完全背包
求小费最小,那就是求花费钱最多完全背包代码:#include#includeint dp[10010];int n;int Max(int a,int b){ return a>b?a:b;}int main(){ int i,j; int a[10]; int T; scanf("%d",&T); while(T-原创 2015-08-07 14:31:42 · 385 阅读 · 0 评论 -
[动态规划]最大连续子序列和
方程: MaxSum[i] = Max{ MaxSum[i-1] + A[i], A[i]}这里可以不用数组for(i=0;i<n;i++) { sum+=a[i]; if(max<sum) { max=sum; } if(原创 2015-08-11 15:00:58 · 353 阅读 · 0 评论 -
HDU 1864(最大报销额)基础0-1背包问题
此题的额度是小数,题目要求2位小数精度,所以把所以额度*100,然后就可以用通用的背包问题解决。个人感觉这方法怪怪的,可能题目数据只有2位小数,如果小数位数3位4位的话,会不会出错,没有验证过。只是为了练习0-1背包问题。题目额度*100的话有点大,O(WV)算法空间不允许,所以用O(W)算法。注意:只能报销A,B,C类,出现别的类别的话发票不报销,某张发票总额和单项总额有限制。原创 2015-07-02 09:55:15 · 478 阅读 · 0 评论 -
HDU 1087(Super Jumping! Jumping! Jumping!)不降子序列和最大
此题就是把不降子序列最长改为和最大代码:#include#includeint main(){ int num[1001],sum[1001]; int i,j,k; int max; int n; while(scanf("%d",&n)!=EOF && n!=0) { memset(num,0,sizeof(num原创 2015-06-24 08:59:25 · 449 阅读 · 0 评论 -
HDU 1423(Greatest Common Increasing Subsequence)公共最长不降子序列
此题其实不想写,写了留个记录吧直接暴力解了,惭愧代码:#include#includeint main(){ int T,i,j,x,y,max; int a[501],b[501],list[501]; int mark1,mark2; int n,m; scanf("%d",&T); while(T--) {原创 2015-06-24 08:55:53 · 356 阅读 · 0 评论 -
HDU 1114(Piggy-Bank)完全背包
完全背包求最少情况初始化无穷大,dp[0]=0;代码:#include#include#include#define MAXNUM 0X3f3f3f3fint dp[50050],p[510],w[510];int n;int Min(int a,int b){ return a>b?b:a;}int main(){ int T; i原创 2015-08-07 14:25:34 · 383 阅读 · 0 评论 -
HDU 3535(AreYouBusy)组合背包的混合背包
这题个人觉得比较难,多种混合的背包。s=0,该组中至少选一种,就和买鞋那题一样,该组的初始化为负无穷,保证不会出现不选的情况,状态转移方程: dp[i][k]=Max(Max(dp[i][k-a[j]]+b[j],dp[i][k]),dp[i-1][k-a[j]]+b[j])。s=1,该组中最多选一件,这样是基本的组合背包问题,用二维是为了方便复制上一层的结果作为本组的初始化。原创 2015-08-10 12:32:16 · 464 阅读 · 0 评论 -
HDU 2639(Bone Collector II)背包问题求第K优解
背包问题求第K优解,此类题在背包九讲里有说到过,刚好也是以01背包为例的:其基本思想是,将每个状态都表示成有序队列,将状态转移方程中的max/min 转化成有序队列的合并。这里仍然以01 背包为例讲解一下。首先看01背包求最优解的状态转移方程:f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}。如果要求第K优解,那么状态f[i][v]就应该是一个大小为原创 2015-08-10 13:01:02 · 390 阅读 · 0 评论 -
HDU 1231(最大连续子序列)动态规划-最大连续子序列和
求最大连续子序列,并求区间位置方法如下:#include#includeint a[10010];int main(){ int n; int i,k,max,sum; int first,last,temp; while(scanf("%d",&n)!=EOF && n!=0) { memset(a,0,sizeof(a原创 2015-08-11 15:14:37 · 418 阅读 · 0 评论 -
HDU 2571(命运)动态规划-数塔问题
从上走到底部,数塔问题。用数塔思想,只是走的方法略微有点差异,下一步可以是(x+1,y),(x,y+1)或者(x,y*k) 其中k>1。数塔方法,从底部往上求,先求最后一行的,然后往前推,为了一定要走大魔王那一格,先把大魔王那格值变大,原题幸运值小于100,可以搞个200什么的,最后减去200加上他原来的值就是所求答案。代码:#include#includeint dp[原创 2015-08-11 14:53:53 · 738 阅读 · 0 评论 -
HDU 1069(Monkey and Banana)动态规划
这题看上去和最长递增子序列好像,需要长和宽都递增,然后求子序列和最大。一块block有6种摆法:高度3种 X 长和宽互换2种,枚举这六种,以长从大到小排序,然后求递增序列和最大,转移方程就是把原来求递增子序列+1改成加高度最大的。代码:#include#include#includeusing namespace std;typedef struct node{ i原创 2015-08-10 15:41:05 · 482 阅读 · 0 评论 -
HDU 2845(Beans)动态规划
题目要求选数和最大,选了这个数,这个数的上下两行和左右两个数就不能选了,不是上下左右那四个数。那就先把每行的最大和(不相邻)算出来最为一个数,然后再同样的方法算一遍这几个数和最大,最后就是要求的和最大。代码:#include#includeint a[200010],b[200010];int Max(int x,int y){ return x>y?x:y;}原创 2015-08-11 13:32:14 · 375 阅读 · 0 评论