
动态规划
leohujx
这个作者很懒,什么都没留下…
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
hdu5375
我们用dp[i][j]来表示第i为数字为j时我们所能得到的最大的值。 那么初始化时我们得将所有的dp[i][j]=-INF 如果第一个字符为’?’或者’1’,那么dp[0][1]=a[0]; 如果第一个字符为’?’或者’0’,那么dp[0][0]=0; 那么在循环里面,也是这样分类 假设第i个字符为’?’或者’1’,那么我们就取dp[i-1][1]和dp[i-1][0]+a[i]这两者之间原创 2015-08-12 16:37:11 · 318 阅读 · 0 评论 -
poj 2184
一道01背包的变形题。 从题目描述中我们可以看出,对于一头牛,我们可以选或者不选,所以这是一个01背包的雏形。然后每头牛有两个值,一个是s,一个是f,我们可以将其中一个当做cost,一个当做weight,那么对应的一个就是dp[i],一个是i,这样全部求出来以后,我们在全部dp[i]>0的情况中寻找dp[i]+i最大的那个即可。 这道题目还有负数的情况,那么我们可以将背包的容量进行一个偏移,题目原创 2015-09-16 16:01:00 · 311 阅读 · 0 评论 -
poj 2392
多重背包问题,这里还要先排序一下,要把限高高度小的放前面,这样子才能将所有的电梯都充分利用起来,如果把高度小的放后面就会造成无法利用。 这里对于每个电梯来说,它们的背包上限就是它们的限高高度。#include<stdio.h>#include<iostream>#include<string>#include<string.h>#include<algorithm>#include<i原创 2015-09-16 11:43:48 · 421 阅读 · 0 评论 -
poj 3666
dp真的要多做才能有门路啊! 我们用dp[i][j]来表示前i个数来表示结尾是整个序列中第j大小的总的代价。 还有一个前提我们是要知道的,就是我们虽然说是修改序列中的某几项使得它成为一个有序序列,但是改完后的数字肯定是序列中本身就存在的,不会修改出一个新的数字来。 比如有三个数a,b,c 假设a#include<stdio.h>#include<iostream>#include<str原创 2015-09-16 10:43:07 · 403 阅读 · 0 评论 -
CF #319 B Modulo Sum
这是一道不错的dp题。 我们用dp[i][j]来代表前j个数能够达到的对m取余的余数,而我们发现j只与j-1有关,可以用滚动数组。那么我们只需要用类似背包的dp来计算出所有可能的结果即可。#include<stdio.h>#include<iostream>#include<string>#include<string.h>#include<algorithm>#include<ioma原创 2015-09-13 22:55:11 · 456 阅读 · 0 评论 -
poj 3181
仔细观察,其实这是一道完全背包的问题,因为每种货币的数量是不受限制的。 然后我们来推测下转移方程 dp[i][j]代表用前j种货币来组成面值为i的方法总数,那么 dp[i][j] = dp[i][j-1]+dp[i-j][j-1],即组成面值为i的可以不用到第j种货币(dp[i][j-1]),也可用到第j种货币(dp[i-j][j-1]),而我们可以发现,它的第二维都为j-1,那么想到背包的知原创 2015-09-10 22:59:32 · 410 阅读 · 0 评论 -
poj 3046
我们用dp[i][j]来代表前i种蚂蚁所能组成规模为j 的蚁群的方法数,那么转移方程应该是 dp[i][j] = (dp[i][j]+dp[i-1][j-k]) 0<=k< N[i] N[i]为第i种蚂蚁的个数,用文字来说,就是前i种蚂蚁组成规模为j的蚁群方法数是由 前i-1种蚂蚁组成j-k种转移过来的,至于j,它为当前蚁群的总数。 而i为1000,j最大为100000,直接开会MLE,我们观原创 2015-09-10 20:58:38 · 281 阅读 · 0 评论 -
poj 1742
这是一道多重背包的题目。 我们可以用多重背包的可行性来对题目进行求解。#include<stdio.h>#include<iostream>#include<string>#include<string.h>#include<algorithm>#include<iomanip>#include<vector>#include<time.h>#include<queue>#inc原创 2015-09-10 16:55:32 · 305 阅读 · 0 评论 -
poj 2385
这道题目是一道经典的dp题。 我们用数组dp[i][j]来表示前i分钟最多走j步所能够接到的最多的苹果,首先处理边界,然后注意走到第i分钟时我们身处的苹果树编号,如果是走了偶数步,那么我们回到了1号树,如果走了奇数步,那么我们走到了2号树。 状态转移方程为 dp[i][j] = Max(dp[i-1][j],dp[i-1][j-1]).即我们在第i-1分钟时要么不走,要么走,就这么两种选择。#i原创 2015-09-09 16:12:15 · 281 阅读 · 0 评论 -
poj 3176
‘金字塔’形的基础dp题 选择一条从上到下的路,使得走过的总权值最大。 我们从下往上dp,每次挑选一个下一行大的与上面一行相加。#include<stdio.h>#include<iostream>#include<string>#include<string.h>#include<algorithm>#include<iomanip>#include<vector>#includ原创 2015-09-09 13:52:38 · 217 阅读 · 0 评论 -
poj 2229
这道题目属于比较典型的递推。 如果一个数i是奇数,我们可以发现,它的组合方法跟i-1肯定是一样的,就相当于在每个i-1方法的后面+1,就可以组合为i. 如果一个数i是偶数,我们就得分类: 1.如果组合方法中有1,那么肯定有偶数个1,也就是我们在i-2的后面+1+1,形成了i. 2.如果组合方法中没有1,那么全部都是偶数,我们只需将所有i/2的组合方法全部*2即可。 举个例子: 比如4,那原创 2015-09-09 15:04:16 · 273 阅读 · 0 评论 -
poj 3280
这道题目名义上赋予了每个字母给了两个值,删除的代价和增加的代价,但是其实只有代价小的有用。理由很简单,对于一个非回文子串来说,增加一个字母和删除一个字母是等价的,比如abb,我们可以发现,有这么两种操作,第一种是将开头的a删除,第二种是在末尾加个a,至于使用哪个,就看删除和增添哪个代价小了,所以说删除和增添是等价的,我们只要留下那个代价小的即可,无需关心到底是删除还是增加。 我们用dp[i][j]原创 2015-09-09 20:32:53 · 335 阅读 · 0 评论 -
poj 3616
比较简单的dp。 转移方程是: dp[i] = Max(dp[i],dp[j]+a[i].ef) //0<=j< i,条件是a[i].st>=a[j].ed#include<stdio.h>#include<iostream>#include<string>#include<string.h>#include<algorithm>#include<iomanip>#include<v原创 2015-09-09 17:15:26 · 307 阅读 · 0 评论 -
hdu5298
题意比较好理解。刚开始没注意n的范围,,用了暴力,结果超时了。 一个比较好的做法就是使用rmq+二分法来查找某个区间的最值。 dpmax[i][j]来代表从下标i开始,一共2^j个元素中的最大值。 dpmin[i][j]来代表从下标i开始,一共2^j个元素中的最小值。对于每个元素的下标i,它符合条件的区间为[1,n-i],我们二分这个区间,看看这个区间内的最小值和最大值之间的差值是否符合题目的原创 2015-07-23 22:37:46 · 634 阅读 · 0 评论 -
hdu 5501
很经典的dp题。。可惜自己dp能力太弱了。。(:зゝ∠) 首先我们看题目,这种一看就是像背包问题,只不过这里的值是会变化的。所以我们就想是否存在一种排序方法,使得背包的结果是最优的。 我们假设有两个题目xi,xi+1,如果不交换它们的顺序,那么我们损失的分数为 ci*bi+1 如果交换,那么损失的分数为ci+1*bi,我们比较下这两个损失的大小。假设 ci*bi+1<=ci+1*bi,那么我们就原创 2015-10-11 10:14:18 · 619 阅读 · 0 评论