DP
Noooooorth
能够放弃的东西从来都不叫梦想
展开
-
HDU 4512 吉哥系列故事――完美队形I(最长公共上升子序列)
从n个人中挑出部分人组成一个队列,使得他们在原队列中的相对顺序不变,同时使得H[1]<H[2]<...<H[mid]<H[mid+1]<...<H[m],H[1]=H[m],H[2]=H[m-1]...原创 2015-08-26 15:33:21 · 1746 阅读 · 0 评论 -
Codeforces Round #341 (Div. 2) E. Wet Shark and Blocks(DP+矩阵快速幂)
题目链接:Problem - 621E - Codeforces一共b位数字,给出1~9出现的次数,从1~9中选,求模x等于b的数字的个数DP[i][j]表示i位数字,模x等于j的数字个数,状态转移方程是dp[k][(i*10+j)%x] += dp[k-1][i]*cnt[j]。观察可以发现dp[k][]的状态只与dp[k-1][]有关,所以直接递推就可以得到正确答案。但是这道题目的原创 2016-07-15 00:20:56 · 441 阅读 · 0 评论 -
NBUT 1222 English Game(trie树+DP)
给出一个目标字符串和n个字符串及其对应的权值,求用这些字符串中的1个或多个组成目标字符串的最大权值。原创 2015-08-19 09:46:29 · 2126 阅读 · 0 评论 -
HDU 1978 How many ways(DP)
每到达一点[i,j]就扫描从这个点能到达的点[i+k,j+l],种数相加即可(dp[i,j]=(dp[i,j]+dp[i+k,j+l])%10000)。原创 2015-07-23 00:53:40 · 1502 阅读 · 0 评论 -
POJ 3280 Cheapest Palindrome(区间DP)
经典的区间DP,对于每个字符,在原字符串加上这个字符的代价是一个值,移除又是一个值,求把原字符串变成回文串的最小代价。经典的区间DP,状态转移方程见代码。在输入进行了一个处理,我们把对一个字符的增与删的操作的代价压缩成为一个数,代表对该字符进行增或删代价,把另一个相对较大的代价则忽略掉。因为在一遍插入一个字符与在另一边删除一个同样的字符对回文串形成的贡献效果一样(可以仔细思考一下)。原创 2015-07-29 17:13:19 · 1810 阅读 · 0 评论 -
POJ 1014 Dividing(二进制优化+多重背包)
题目大意:有权值分别为1,2,3,4,5,6的大理石,每种都有若干块,也可能没有,问你能否把它们分成权值相等的2份。大理石的总数量不超过20000。普通的多重背包时间复杂度为O(V*Σn(i)) V为空间容量,n(i)为每种石头的数量限制。题目看上去是多重背包,背包容量为石子权值总和的一半。但是我们可以通过二进制优化将其变成01背包(详见背包九讲V2.0章节2.4)。所谓的二进制优化就是把一个正整数拆成2^n之和和剩余的数。比如17,我们先拆分出1,然后是2、4、8,这是我们发现如果再往后拆的话1+2+原创 2015-07-29 17:07:48 · 1925 阅读 · 0 评论 -
POJ 1837 Balance(DP)
给出C个挂钩的位置以及G个重物的质量,求有几种方式使得天平平衡。这道题乍看要用搜索,其实DP就可以。dp[i][j]表示挂完前i个重物能使力矩为j的情况种数,j=0时表示平衡。所以状态转移方程就是dp[i][k+loc[j]*wei[i]]+=dp[i-1][k],表示前(i-1)个重物挂完后合力矩为k,这时在第j个挂钩处挂上重物i,则两者要相加,即dp[i][k+loc[j]*wei[i]]就要加上dp[i-1][k]。有一点要注意,力矩可能为负数,所以dp数组的下标可能越界,所以要把力矩加上一个力原创 2015-07-26 23:23:02 · 1729 阅读 · 0 评论 -
POJ 2479 Maximum sum(双向DP)
1000ms,50000个数,所以每次处理的时间复杂度不能超过nlogn,否则会超时。所以要让最后扫描一次就能求出答案。基本思路就是第一次遍历先定义2个数组,分别记录前i项和(含i)与后i项和(含i)。第二次遍历再定义2个数组,分别记录以i为终点(含i)的最大子段和与以i为起点(含i)的最大子段和。第三次遍历再定义2个数组,分别记录第i项(含i)的之前的最大子段和与第i项(含i)的之后的最大子段和。最后遍历一遍数组求出i之前(含i)子段和与i之后(不含i)子段和的最大值即可。原创 2015-07-26 23:26:10 · 1831 阅读 · 0 评论 -
POJ 3071 Football(概率DP)
编号分别为1、2、3……2^n的2^n个队伍参加比赛,每一轮相邻的两两比赛,胜者晋级下一轮,负者淘汰,直到只剩下一支队伍。基本思路:dp[i][j]表示第i轮比赛j号队胜利的概率,第i轮j要获胜,首先第(i-1)轮j要获胜,(所以dp[0][j]要初始化为1),用k表示能与k在第i轮比赛中相遇的对手,而且如果j与k要相遇,k也必须在第(i-1)轮中获胜,所以状态转移方程为dp[i][j]+=dp[i-1][j]*dp[i-1][k]*p[j][k],注意,是相加,即把遇到每个对手且获胜相加就是j在这一轮获原创 2015-07-26 23:30:07 · 1747 阅读 · 0 评论 -
POJ 1948 Triangular Pastures(DP)
给出n条边,输出这n条边组成三角形的面积的最大值*100。数据范围是边数不大于40,每条边长度不大于40。所以我们可以尝试可不可以暴力求解。首先定义一个数组dp,dp[i][j]表示三角形一条边长为i,一条边长为j的情况存不存在。那么状态转移方程就是dp[j][k]|=(dp[j-e[i]][k]||dp[j][k-e[i]]),表示j或k是否可以由原来的边加上某条边得到。若由j,k,(sum-j-k)形成的三角形存在,计算出所有的最大值。原创 2015-07-29 17:09:49 · 1094 阅读 · 2 评论 -
HDU 3033 I love sneakers!(01背包变形)
题目的难点就在于每种牌子至少选一种。网上好多人说这道题属于分组背包,但我认为这道题只是一道加了条件限制的01背包。但这个不重要(手动斜眼)。首先把各个品牌的鞋子放到各自对应的vector中,然后遍历每种品牌的每双鞋,再然后就是我们熟悉的for(int k=V;k>=brand[i][j].w;k--)了。但在状态转移的时候我们要加上一个判断,从当前我们要选的品牌转移来的状态不用判断,因为是否选择当前的一双鞋与本组内是否有鞋被选无关。而从上一组转移状态要加上一个if判断句,判断上一组是否有鞋被选中,如果没有原创 2015-07-29 17:07:12 · 1931 阅读 · 1 评论 -
POJ 1159 Palindrome(区间DP/最长公共子序列+滚动数组)
给一个字符串,计算最少加多少个字符能够使字符串变成回文串(即从前往后读与从后往前读一样)。有2种思路,一种是直接区间DP,dp[j][i]表示[i,j]这个子串要变成回文串需要添加多少个字符,状态转移方程如下:if(s[i]==s[j]) dp[j][i]=dp[j+1][i-1];else dp[j][i]=1+min(min[j+1][i],min[j][i-1])第二种思路也比较容易想,要将一个字符串变为回文串,那么我们原创 2015-07-26 23:56:38 · 2125 阅读 · 2 评论 -
ACdream 1216 Beautiful People(二路最长上升子序列 O(nlogn) )
从n个人中挑选出若干人,使得这些人中的任何一个人的两种属性同时大于或同时小于其他人。输出最多能挑选出的人的个数和编号。原创 2015-08-27 19:44:47 · 1326 阅读 · 1 评论 -
HDU 3336 Count the string(KMP+DP)
给出一个字符串,输出每个前缀在原串中出现的次数总和。原创 2015-08-26 15:41:40 · 1798 阅读 · 0 评论 -
SGU 149 Computer Network(树形DP)
题目链接:点击打开链接题目大意:给出从2~n号节点的父节点与其和父节点的距离,输出每个节点到树中节点的最大距离。解题思路:第一遍DFS,用deep[i][0]记录节点i到其子节点的最大距离,deep[i][1]保存次大距离。第二遍DFS,deep[i][0]的意义变成了节点i到树中节点的最大距离,deep[i][1]为次大距离。由于根节点1的deep[1][0]表示的就是距离树中节点的原创 2016-07-21 01:36:10 · 639 阅读 · 0 评论