![](https://img-blog.csdnimg.cn/20201014180756927.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
动态规划
弱者
爱猫忍者
展开
-
这就是传说中的复试上机题
一个整数总可以拆分为2的幂的和,例如:7=1+2+47=1+2+2+27=1+1+1+47=1+1+1+2+27=1+1+1+1+1+27=1+1+1+1+1+1+1总共有六种不同的拆分方式。再比如:4可以拆分成:4 = 4,4 = 1 + 1 + 1 + 1,4 = 2 + 2,4=1+1+2。用f(n)表示n的不同拆分的种数,例如f(7)=6.要求编写程原创 2014-02-08 19:37:05 · 1067 阅读 · 0 评论 -
黑书 舞蹈家怀特先生
很棒的题目,锻炼了心理素质。#include#include#includeusing namespace std;int dp[10005][5][5];bool flag[10005][5][5];int ko[10005];int mini(int a,int b){ if(a<b) return a; return b;}int count(int x,in原创 2013-08-23 20:44:25 · 907 阅读 · 0 评论 -
poj 2393 yogurt factory
不用多说的简单题目。关键在于到底生产的价格使用的是哪一个,需要保存一个最小的价格就好了,慢慢琢磨吧程序写的很明白。#includeusing namespace std;long long pri[10005],need[10005];int main(){ long long n,s,sum; long long lowest; cin>>n>>s; for(int i=1;原创 2013-08-09 18:03:29 · 587 阅读 · 0 评论 -
poj 1191 棋盘分割
刘汝佳黑书上的题目。没什么好说的,就是记忆化搜索,懒人必备的动态规划算法。#include#include#include#includeusing namespace std;int s[9][9][9][9];int dp[15][9][9][9][9];int map[9][9];int n;int mini(int x,int y){ if(x<y) retu原创 2013-08-08 22:53:58 · 718 阅读 · 0 评论 -
poj 1163 the triangle 记忆化搜索
最近刚看了刘汝佳讲的记忆化搜索,不错。以后动态规划可以自上而下的进行求解了,哈哈。原来的递归的那个自下而上的以前写过博客不提。#includeusing namespace std;int dp[101][101];int map[101][101];int n;int maxi(int a,int b){ if(a>b) return a; else return b;}原创 2013-08-08 18:02:05 · 599 阅读 · 0 评论 -
poj 1141 brackets sequence
这个题目和刘汝佳的题目一样,就是多了一个让你输出一种补全的匹配情况。就是记录下每个匹配到底是怎么来的就好了。#include#include#includeusing namespace std;char bra[101];int dp[101][101];int store[101][101];bool match(char x,char y){ if((x=='('&&y原创 2013-08-07 22:56:06 · 537 阅读 · 0 评论 -
poj 3181 Dollar Dayz
高精度是着实没有想到,参考的别人的。这个dp本来是比较简单的可惜了数据比较小,我写的麻烦的做法都能过。这个题目简单的做法和整数划分的一种很像,有兴趣的可以找找看看。先贴上麻烦的代码。#includeusing namespace std;long long dp[105][1005];long long ko[105][1005];int main(){ int n,k,i,j,x原创 2013-08-07 18:11:21 · 555 阅读 · 0 评论 -
poj 2955 brackets
刘汝佳书上的题目,虽然不太一样,但是实质上是一样的。同学们可以参看黑书113页。#include#includeusing namespace std;int dp[100][100];string bra;bool match(char x,char y){ if((x=='('&&y==')')||(x=='['&&y==']')) return true; else原创 2013-08-07 11:46:58 · 605 阅读 · 0 评论 -
poj 3276 the cow lexicon
感觉不错,除了数组大小第一次开错了,wa了一次。动态规划的边界处理有点麻烦。这个题目的意思就是说,牛说了一句话,然后里面可能有一些无意义的单词,牛有一本词典,里面有些单词,现在让你在这句话中去掉一些字母然后让剩下的这些都有意义。问最少去掉多少词。dp[i]=min(dp[i],dp[j]+i-j+length[k]),其中dp[i]表示到下标i最少去掉多少词,length[k]代表第k个单词的长度原创 2013-08-04 21:41:43 · 690 阅读 · 0 评论 -
hdu 2844 coins
这个题目直接悲剧了超时不知道多少次了,连二进制都用上了,这个不科学啊。今天突然理解到其实刚开始把所有的状态全部赋值为0,也就是这个状态是不可达的,当然dp[0]=1这个是初始化。然后后面按照背包直接来就好,以前的时候我们是这么写的(我已经用二进制做了,所以直接写了,具体操作看代码)dp[k]=max(dp[k],dp[k-w[i]]+v[i]);现在其实只要dp[k]==1我们就不用管,反之看一下原创 2013-06-04 11:37:03 · 895 阅读 · 0 评论 -
poj 3941 expected allowance
在初始化上吃了亏。犯了兵家大忌。#include#include#include#include#includeusing namespace std;int dp[2][100000008];int main(){ int n,m,x,sum,i,j,k; while(scanf("%d%d%d",&n,&m,&k)!=EOF) { if(n==0&&m==0&&k原创 2013-08-24 23:07:05 · 1116 阅读 · 0 评论 -
nyoj 掷骰子
啥话都不说上程序,简单的没话说。#include#include#include#include#includeusing namespace std;int dp[11][66];double ko[11][11];int main(){ int i,j,k,p; double sum,all; for(i=1;i<=6;i++) { dp[1][i]=1;原创 2013-08-25 20:53:13 · 799 阅读 · 0 评论 -
hdu 2639 Bone Collector II
01背包变种。可惜写的时候有个变量写错了检查了一晚上,被坑惨了,以后变量名可要注意了。#include#includeusing namespace std;int A[33];int B[33];int dp[1005][33];int value[105],weight[105];int main(){ int t,n,i,v,k,j,kk,traget; cin>>t原创 2013-08-14 22:27:49 · 594 阅读 · 0 评论 -
hdu 4632 Palindrome subsequence
这个题目让你求一个字符串中所有的回文串的个数。这个题目对于什么样的算不重复有这要求,仔细阅读。dp(i,j)表示从第i个字符到第j个字符回文串的个数,dp(i,j)=dp(i+1,j)+dp(i,j-1)-dp(i+1,j-1),这个是因为两端是新更新的,所以首先可有以前求解出来的来表示i或者j至少有一个不算在内有多少个回文串,当然要去掉重复的。然后如果s[i-1]==s[j-1]那么也就是说,两原创 2013-08-29 16:55:19 · 654 阅读 · 0 评论 -
hdu 4681 string
这个题目就是说现在给你三个字符串a,b,c,要求求出一个字符串d要求长度最大,并且要求d是a,b的子串(注意这个子串没要求字符是连续的),然后c必然是d的连续子串。现在求这个长度。注意到无论如何d串中必然有连续子串c,现在只需要知道c在a,b中的开始位置和结束位置(注意,一旦开始位置选定,结束位置的下标要最小),然后枚举这些位置,分别求出最长公共子序列就好了。附带一组数据,abcddc,bcdd,原创 2013-08-29 10:12:37 · 658 阅读 · 0 评论 -
hdu 3535
以前不会做的题目,看完分组背包后突然就会做了。#includeusing namespace std;int dp[105][105];int cost[105],value[105];int maxi(int a,int b){ if(a>b) return a; else return b;}int main(){ int n,t,i,j,m,s,k; whil原创 2013-08-16 21:41:41 · 874 阅读 · 0 评论 -
hdu 3033 i love sneakers
这个题目就是说,现在这个小孩去买鞋,然后一共有n种不同的原则,b种品牌,当然每个品牌都有一个价格(当心价格可能是0),小孩还给每个鞋子一个价值。现在小孩拿着m元钱去买鞋,要求每种品牌的鞋子都至少要买一双,问他能获得的最大价值是多少。这个题目是分组背包,但是注意和背包九讲的区别,背包九讲里的那个是每种鞋子最多购买一种。注意循环的时候的顺序。注释的语句很容易的帮你查找对错。#include#in原创 2013-08-16 18:49:10 · 719 阅读 · 0 评论 -
hdu 4341 gold miner
受教了。这个题目是本人第一次做分组背包,比较失败。连题意带条件搞错了几个地方,最终悲剧的wa了4次。#include#include#includeusing namespace std;struct node1{ int heng; int zong; int w; int v;};int num[205];node1 point[205];int cost[205]原创 2013-08-15 22:14:13 · 781 阅读 · 0 评论 -
poj 1390 blocks
刘汝佳黑书上的题目。书上解释的很详细了,不说了。#include#includeusing namespace std;int dp[205][205][205];int color[205],len[205];int maxi(int a,int b){ if(a>b) return a; return b;}int dfs(int start,int end,int原创 2013-08-27 14:48:09 · 782 阅读 · 0 评论 -
hdu 1913 computers
关键是理解意思。要点一,这个题目要在所有的n年都有电脑,也就是说第一年的时候必定先买电脑;要点二,到第i年的最少花费,必然是不知道从第几年买电脑,并且一直使用到了第i年;要点三,矩阵中的信息是从第i年买电脑,到第j年总的维修费,只是维修费,买电脑的钱没在里面。题目很黑啊,没给数据范围,我的程序到1000就过了。#include#includeusing namespace std;int原创 2013-08-27 16:11:20 · 997 阅读 · 0 评论 -
poj 3624 charm bracelet
这么水的题目竟然都有人做错,不可思议。#includeusing namespace std;long long weight[3500],value[3500];long long dp[13000];long long maxi(long long a,long long b){ if(a>b) return a; else return b;}int main()原创 2013-08-14 22:43:46 · 563 阅读 · 0 评论 -
hdu 4597 play game
有点博弈论味道的动态规划,这个题目再次凸显了记忆化搜索的便利之处,找好边界后接着就是深搜的写法了。由于每次只能取4个位置的一个位置,并且要考虑到对手怎么取,由于对手的策略是相同的,所以他也是从4个里面取出一个。这个题目关键是对手的策略是和你相同的。#include#include#includeusing namespace std;int dp[25][25][25][25];in原创 2013-08-26 22:57:36 · 760 阅读 · 0 评论 -
hdu 4545 魔法串
其实说白了就是最长公共子序列,就是第二个序列是可以相应的进行变化的。其实用一个数组存一下这个到底是哪个字符可以相应的变成对应的字符就可以了。水题不解释贴代码。#include#includeusing namespace std;int dp[1005][1005];bool has[128][128];int maxi(int x,int y){ if(x>y) retur原创 2013-05-31 12:16:46 · 818 阅读 · 0 评论 -
hdu 1856 more is better 并查集
又是一个并查集的题目,这个题目的意思就是刚开始房间里有10000000个人,然后现在让你选择出来部分人,要求是这些人是朋友(直接的和间接的),然后要求选出来的这个组人数要求是最多的。这个题目和virtual friends的做法是相同的,都是设置一个数组来记录包括这个人的朋友圈当前有多少人。最后只需要遍历一遍看看哪一个的father[i]==i然后选出来那个的sum要求是最大的。下面是代码。原创 2013-05-13 23:39:15 · 978 阅读 · 0 评论 -
POJ 1050 to the max最大子矩阵
比较经典的DP题目,题意就是给你一个大矩阵然后让你找到一个子矩阵使得该矩阵云素和最大.这个题目的优化很厉害的,直接枚举起始位置然后用最大子段和求解.下面是代码.#includeusing namespace std;int ko[105][105];int b[105];int dp[105];int main(){ int N,i,j,k,maxi,p,jo;原创 2013-04-15 18:55:58 · 777 阅读 · 0 评论 -
poj1014 &&hdu 1059dividing
本人用动归做的,多重背包的二进制优化。有点可惜wa了几遍,竟然是改变了一个变量的值。弱智错误,导致本人这个题加上以前的差不多敲了20遍吧。 #includeusing namespace std;int marble[20020];int dp[120020];int ko[7];int maxi(int a,int b){ if(a>b) return a; else原创 2013-04-14 23:33:50 · 615 阅读 · 0 评论 -
HDU 1574 RP问题
省赛明天就选拔了,人品有木有。这个题的意思就是你干好事的时候呢,人品值是上升的+a,但是必须是你的当前人品要低于或者等于b的值,然后你的获益是+c。反之就全都是反着的。然后呢,由于题目的变量的范围以及可能出现负人品的情况,所以初始的值+10000,也就是初始值是10000。然后我们设置一个visited数组记录这个人品值有没有可能达到。当然最后的结果得总的遍历一遍,嘿,竟然不超时。贴上代码,解原创 2013-04-10 22:08:36 · 979 阅读 · 0 评论 -
hdu 1561 the more,the better
第一个树形DP。这个题既是dp又是dfs和背包。dp[i][j]表示当前访问节点序号是i,且访问j次其子节点。dp[i][j]=max(dp[i][j],dp[i][j-r]+dp[t][r])。t为i的一个子节点。详细的看代码。#include#includeusing namespace std;vector tree[201];int dp[201][201];//int va原创 2013-03-27 16:13:41 · 1426 阅读 · 0 评论 -
hdu 1423 最长公共递增子序列
刚刚习得这一技巧,做的太好了,可以直接拿来当模板用。估计也不会有什么变式之类的麻烦的东西。直接贴代码,太短了,一看就记住了。#includeusing namespace std;int a[505],b[505],f[505];int main(){ int T,i,n1,n2,j,k,max; cin>>T; for(i=1;i<=T;i++) {原创 2013-04-09 10:29:20 · 794 阅读 · 0 评论 -
hdu 1513 Palindrome最长公共子序列
通过这个题学到了很多东西,尤其是滚动数组的优化太精彩了。下面先写上我对应用滚动数组的一些想法。先看下面的动态转移方程,dp[i][j]=max(dp[i-1][j],dp[i][j-1]),我们首先能看出i-1与i的奇偶性是一定不同,所以我们模2之后的结果是不变的,也就是dp[i%2][j]=max(dp[(i-1)%2][j],dp[i%2][j-1])的效果和原来的效果是一样的。下面看代码。空原创 2013-04-08 22:33:45 · 789 阅读 · 0 评论 -
hdu 4501 买年货
这个题起初做的时候想的是,先尽量把钱花完,在尽量把积分花完,因为你不能混着用钱和积分,然后再把剩下的排个序,取出前面最大的。但是有点麻烦,不知道怎么记录买了哪些商品。然后就麻烦了,写了一个4重循环的程序。直接贴代码,比较好理解,钱能买用钱买,钱不行用积分,再不就白拿。其实是3个01背包然后取的价值最大值。#includeusing namespace std;struct good{ i原创 2013-03-24 15:57:24 · 822 阅读 · 0 评论 -
HDU 1421 搬寝室
这道题和上一篇chopsticks很相似。直接附上代码。#include#includeusing namespace std;int cmp(int a,int b){ return a<b;}int min(int a,int b){ if(a<b) return a; else return b;}int good[2001];int dp[1001][2001原创 2013-03-18 10:43:59 · 719 阅读 · 0 评论 -
hdu 1500 chopsticks
这个题真是自己想没想出来,连看书带看代码才弄明白的。都是自己太弱了。我们先把所有数据排序,按照从大到小的顺序。dp[i][j]表示从前j组选出i双这种3个一对的筷子,那么就有第j双是选还是不选的问题了,则可知dp[i][j]=min(dp[i][j-1],dp[i-1][j-2]-(chopstick[j-1]*chopstick[j-2])^2),若不选即为前一状态,如果选了最后一只,注意是原创 2013-03-18 09:54:14 · 795 阅读 · 0 评论 -
poj 1080&&hdu 1080 human gene fucnction
#include#includeusing namespace std;int a[105];int b[105];int dp[105][105];int ko[5][5]={{5,-1,-2,-1,-3},{-1,5,-3,-2,-4},{-2,-3,5,-2,-2},{-1,-2,-2,5,-1},{-3,-4,-2,-1,0}};int maxi(int a,i原创 2013-04-15 19:53:30 · 883 阅读 · 0 评论 -
poj 1036 Gangsters
POJ的第2个题。也是动归,其中dp[i][j]表示是第i个时刻,门开到j的程度时的最大价值。当然了状态比较好想的,此时刻的价值必然与前面的时刻是有关的,联系就是前一个时刻的j,也就是与前一时刻的门的程度是相关的,并且一个时刻门只有三种可能。1:开一个单位。2:关一个单位。3:与之前的一样。并且要使用滚动数组来做这个,不然我的内存可能会超,没试过因为这种动态转移方程一般都用滚动数组来节省空间,原创 2013-04-15 15:51:43 · 1036 阅读 · 0 评论 -
POJ 1952 buy low,buy lower
非常漂亮的动归题目,程序里面的问题都是自己找出来的,做了3天,比较爽。这个题目说白了就是先让你求最长递减序列的长度,然后去掉重复的。这个题目关键在于去掉重复的。a[i]表示所储存的元素,然后是dp[i]表示到第i个元素的时候(包括这个元素)的最长递减序列的长度,count[i]是用来记录到第i个元素长度是dp[i]的所有结果有多少个。现在分析去重问题。这是这组数据的结果,dp[i]的求法就原创 2013-04-29 14:21:52 · 1404 阅读 · 0 评论 -
hdu 1503 advanced fruits
题目的意图就是考察最长公共子序列,顺带着考察一下这个题目怎么用回溯法输出这个子序列。#include#include#includeusing namespace std;char str1[120],str2[120];int dp[120][120],ko[120][120];void dfs(int l,int n){ if(l==0&&n==0) return ;原创 2013-05-24 21:41:51 · 628 阅读 · 0 评论 -
hdu 2159 fate
二维费用背包,第一个消费是忍耐值,第二个消费是杀怪数目。dp[i][j]表示杀了i个怪时剩余j的忍耐度。这个题目整个是二维背包套用完全背包的类型。比较有代表性。注释在代码里面#includeusing namespace std;int dp[105][105];int v[105],cost[105];int maxi(int a,int b){ if(a>b) return原创 2013-05-06 18:18:28 · 772 阅读 · 0 评论 -
poj 1925 spiderman
这个题目无疑我被坑惨了,就是因为这个问题丫的一个程序,这么写cin>>t;while(t!=0){中间略过;t=t-1}就wa。这么写cin>>t;while(t--){中间略过;}就AC。一晚上我写了10几遍啊。坑死了。题目是好题,其实比较好想,这个与之前走过路有关。dp[i]表示跳到i位置的时候最少跳多少次,但是可能有的位置你跳不到,所以开始全部赋值为-1就好了,如果当原创 2013-05-04 23:20:13 · 853 阅读 · 0 评论 -
poj 1157 LITTLE SHOP OF FLOWERS
花瓶插花,比较水的题目。dp[i][j]前i朵花插入前j个花瓶得到的最大价值。关键就是第i朵花的归属问题。必然是dp[i][j]=maxi(dp[i][j-1],dp[i-1][j]+value[i][j]),要用这个的前提就是j-1>=i。下面是代码。#includeusing namespace std;int value[105][105];int dp[105][105];原创 2013-05-03 22:08:30 · 763 阅读 · 0 评论