动态规划
文章平均质量分 63
fengsigaoju
本科:南京邮电大学
座右铭:凤兮凤兮思高举!
展开
-
动态规划之背包问题初研究
有N件物品和一个容量为V的背包。第i件物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使价值总和最大。原创 2015-09-27 11:29:49 · 560 阅读 · 0 评论 -
poj3254(状态压缩dp)
//状态转移方程:dp[i][k]=求和(dp[i-1][t])(其中k和t是上下没有一个庄稼在同一行,这个状态怎么表示就是用压缩,比如上一行是101,这一行是010就可以)所以dp[i][5]肯定包含dp[i][2]//&运算,按位与运算//比如8&10,其中8的二进制是0000 1000,而10的二进制是0000 1010,因此// 0000 1000(十进制8)//原创 2016-02-21 18:32:18 · 317 阅读 · 0 评论 -
矩阵链乘(动态规划)
核心语句:ans=min(ans,d[i][k]+d[k+1][j]+m[i]*m[k+1]*m[j+1]); 其中m[i]*m[k+1]*m[j+1]可以类比普通求矩阵的代码#include #include int m[1005]; int d[1005][1005]; int n; int min(int a,int b) { return a<b?a:b;原创 2016-02-23 10:08:51 · 565 阅读 · 0 评论 -
完全背包hdu1248
不死族的巫妖王发工资拉,死亡骑士拿到一张N元的钞票(记住,只有一张钞票),为了防止自己在战斗中频繁的死掉,他决定给自己买一些道具,于是他来到了地精商店前.死亡骑士:"我要买道具!"地精商人:"我们这里有三种道具,血瓶150块一个,魔法药200块一个,无敌药水350块一个."死亡骑士:"好的,给我一个血瓶."说完他掏出那张N元的大钞递给地精商人.地精商人:"我原创 2016-02-23 18:23:47 · 610 阅读 · 0 评论 -
LCS最长公共子序列入门题
如果a[i]=b[j]那么dp[i][j]=dp[i-1][j-1]否则,dp[i][j]=max(dp[i-1][j],dp[i][j-1]最后dp[l1-1][l2-1]存的就是个数其实最好应该从1~n但是考虑到数组下标为-1时也为1,所以这种情况可以忽略#include #include char a[1005]; char b[1005]; int dp[10原创 2015-12-23 12:52:36 · 352 阅读 · 0 评论 -
hdu1159(最长公共子序列)
坑的一笔,我脑残了,一直wa,原来的代码是从0开始遍历,这样if (a[i]==b[j])dp[i][j]=dp[i-1][[j-1]就会数组下标越界,所以经过修改才正确.附AC代码:#include #include char a[505];char b[505];int dp[505][505];int max(int c,int d){ return c>d?c:原创 2016-02-23 22:04:04 · 1687 阅读 · 0 评论 -
hdu1207
多了一根柱子,还是原来的移动方法,只不过原来是先将n-1移开,再移动剩下1个,而现在多了一根柱子,所以可以先将原来x根借助两根柱子移开,再将剩下拉的n-x借助一棵柱子移开(2^(n-x)-1),状态转移方程f[n]=min(f[j]*2+2^(n-j)-1)#include #include __int64 f[70];__int64 ans;void dp(){ int i,原创 2016-02-24 10:27:09 · 597 阅读 · 0 评论 -
硬币找零问题(完全背包)
#include #include int a[100];int dp[100][1000];int min(int a,int b){ return a<b?a:b;} int main() { int n,m,i,j,k,ans; scanf("%d%d",&n,&m); for (i=1;i<=n;i++) scanf("%d"原创 2016-02-25 11:07:09 · 1371 阅读 · 1 评论 -
连续邮资问题(回溯+动态规划)
这个程序debug了好长时间....一个晚上都耗上面了这个程序实际上每一部分并不复杂,但是动态规划那边边界错了好长时间。题目:假设国家发行了n种不同面值的邮票,并且规定每张信封上最多只允许贴m张邮票。连续邮资问题要求对于给定的n和m的值,给出邮票面值的最佳设计,在1张信封上可贴出从邮资1开始,增量为1的最大连续邮资区间。例如,当n=5和m=4时,面值为(1,3,11,15,32)的5种邮票原创 2016-02-25 22:07:45 · 12994 阅读 · 3 评论 -
hdu2151
简单dp,状态转移方程dp[i][j]=dp[i-1][j-1]+dp[i-1][j+1];(其中dp[i][j]代表第i秒到达第j棵树的方案)注意循环顺序,先把之前一秒的所有树的方案推完才能推出这一秒的树的方案.#include #include int dp[105][105];//dp[i][j]到代表第i秒到达第j棵树的方法 int main() { int n,原创 2016-03-12 20:51:48 · 605 阅读 · 0 评论 -
遗传算法解决背包问题
//总体思想与之前的相似,评价函数就是物品的价值之和,但要注意一旦物品的重量大于背包的重量,那么该条染色体的幸存概率为0//基因就是每一个物品是否选择,这里默认有10条染色体在比较,并且每一条染色体上的第i个基因就是代表第i个物品是否选择//突变就是随机选择的染色体的随机位置由0变1,由1变0//另外建议把变异的概率调高点,否则有可能会陷入局部最优#include #includ原创 2016-02-29 23:10:28 · 7720 阅读 · 4 评论 -
算法课实验
LCS的实验,注释写的比较详细.#include #include char a[505];//第一个序列char b[505];//第二个序列int dp[505][505];//dp[i][j]是在第一个序列的第i个字母和第二个序列的第j个字母时的最长公共子序列char result[505];//存储解int num;//存储解的个数int main(){ in原创 2016-05-16 20:25:20 · 349 阅读 · 0 评论 -
poj1050(最大子矩阵和)
首先复习一下最大字段和:一般有两种写法int dp(int sum[105],int k){ int i,b,max; max=sum[0]; b=sum[0]; for (i=1;i<k;i++) { if (b<0)//如果之前的和小于0 b=sum[i]; else b=b原创 2016-02-14 11:45:31 · 459 阅读 · 0 评论 -
poj1157(两种不同的解法)
题目大意是有f种花插入v种花盆中,告诉你a[i][j](第i种花插入第v个花盆中的高兴值),注意若x种花用了第y种盆子,则下一种花只能在y+1~v种选择自己想出来的状态转移方程是f[i][j]=max(f[i-1][k])+a[i][j](i-1写出伪代码for (i=1;i<=f;i++) for (j=1;j<=v;j++) { ans=min; f原创 2016-02-13 18:32:48 · 730 阅读 · 1 评论 -
noj1031建筑群最长坡值
最长递减序列,状态转移方程dp(i)=max(dp(j))+1(jDescription建筑群所有建筑高度分别为h1、h2…hN,可以得到一些单调递减的序列hi1、hi2…hiK,其长度称为建筑群的坡值,这里1≤i1≤N。你的任务:对于给定的建筑群所有建筑高度,求出建筑群最长坡值。Input第一行是建筑群中的建筑数N(1≤N≤1000)。第二行依次给出各个建筑的高度(大小从0到10原创 2016-02-12 19:52:20 · 367 阅读 · 0 评论 -
背包问题
//悼念512大地震#include #include int max(int a,int b){ return a>b?a:b;} int main() { int n,m,i,j,T,l; int v[105],w[105],k[105]; int f[105][105]; scanf("%d",&T);原创 2015-11-26 23:28:59 · 285 阅读 · 0 评论 -
简单dp(codeforce #336(c)补题
简单dp(codeforce #336(c)补题原创 2015-12-30 20:42:41 · 495 阅读 · 0 评论 -
最长上升子序列
最长上升的O(n^2)的方法是我看过最简单的DP了~~拿POJ 2533来说。Sample Input71 7 3 5 9 4 8Sample Output(最长上升/非降子序列的长度)4从输入的序列中找出最长的上升子序列(LIS)。d(i)=max(1,d(j)+1)其中(a[i]>a[j])其中这里的i,j均为下标。含义是讨论到第i个数的最长上升子序列,原创 2015-12-16 21:24:09 · 331 阅读 · 0 评论 -
DP入门题--数塔问题(poj1163)
做了10来道DP题再做这个数塔问题明显上手,不仅写的快,一次AC,还用了两种方法。由此看来深入浅出不是没有道理啊,哈哈~~数塔问题的状态转移方程很容易得到,我是从上往下想的(即递推的思想),这里说一下经常看到的两种DP的写法,一种是用递推的方式,它的要求是每一次求的这个状态,它计算肯定是由前面已经算出来的状态得到的,比较容易实现,但是不是每一道题都那么容易想出,另一种是记忆化搜索的方式, 即我原创 2015-11-30 18:07:05 · 940 阅读 · 0 评论 -
poj1014
#include #include int max(int a,int b){ return a>b?a:b;}int main() { int dp[70000]; int w[70000]; int a[7],sum,i,j,time=0,k,m,count,temp; while(1) { time++;原创 2015-11-30 00:18:12 · 450 阅读 · 0 评论 -
poj2184
//此题有助于理解滚动数组里面内存循环的顺序,当求dp[j]时,默认dp[j-w[i]]是dp[i-1][j-w[i]]这就要求在求dp[j]之前,dp[j-w[i]]不能改变(如果更改了,那么dp[j]就是用的更新//过的值。如果w[i]为正,那么j-w[i]<w[i]所以从大到小,先访问w[i]再访问j-w[i](如果先算dp[j-w[i]]那么它如果被更新,dp[j]就错了)如果w[i]原创 2015-11-30 00:16:17 · 538 阅读 · 0 评论 -
poj1887
类似LIS,只不过判断是从大到小,你妹,括号放错位置了,白白wa了3次。。。#include int s[10000006]; int main() { int i,j,n,temp,top,num; num=0; while((scanf("%d",&n)==1)&&(n!=-1)) { num++; top=1; s[原创 2015-12-18 13:43:07 · 575 阅读 · 0 评论 -
hdu4472
这也是一个dp问题,关键在于每一个子树所拥有的节点数相等,这说明这棵树是十分对称的,即假设我根节点是4然后子数只能是1和2,因为如果是3,那么左右两边数量不等,其次,如果选择了子树为2,那么这两个子树还必须长得一模一样,因为他们又分别是以2为节点的数,子节点只能是1.而我要求第i层的数必定要求i-1的因数(除去根节点自己),然后再求i-1的子树,而此时i-1的子数已知,可以递推.因此得原创 2015-12-21 11:09:14 · 465 阅读 · 0 评论 -
codeforces#336 div2 A,B
codeforces codeforces#336 div2 A,B原创 2015-12-24 12:29:09 · 300 阅读 · 0 评论 -
poj1088(dp入门题)
//传说中的入门题,啊啊啊,说明最近还是有长进的,边吃着外卖边码代码,外卖吃完代码也写好了,一次AC~~//思路相当简单啊,就是记忆话搜索,有过这个值就记录下来,如果这个点没有访问过,则从这个点搜索。#include #include int s[105][105];int dp[105][105];int r,c;int max(int c,int d){ retur原创 2015-12-24 19:11:24 · 649 阅读 · 0 评论 -
最大连续两段不相交字段和(poj2594,poj2479)
首先说一下连续字段和的求法动态方程很容易推出b(i)=max(b(i-1),0)+a[i];定义b(i)为以i为结尾的最大连续和(注意这边是以i结尾,一定包含i,而如果我是求到第i个最大值还需要求出所有1~i的b(i)中的最大值)00000,最后再求出最大的b(i) l[0]=a[0]; for (i=1;i<n;i++) { if (l[i-1]>0)原创 2016-02-12 16:26:17 · 635 阅读 · 0 评论 -
数组分割
我是不是写过的....记不清了,反正博客没找到,记录一下.dp[i][j]代表:用i个物品装空间为j能否装的下,状态转移方程:dp[i][j]=dp[i-1][j-w[k]](如果dp[i-1][j-w[k]]为真)import java.util.Scanner;public class 数组分割2 { public static void main(String[]原创 2017-04-04 22:19:27 · 946 阅读 · 0 评论