随笔分类 - 动态规划
摘要:dp[i][j]代表选了i个人,D(J)-P(J)的值为j的状态下,D(J)+P(J)的最大和。#include #include #include #include using namespace std;const int MAXN = 810;int n, m;int dp[24][MAXN];int path[24][MAXN];int P[210], D[210];int sub[210], sum[210];int maxval, fix;int ans[210];bool IfHave( int i, int j, int k ){ while ( i > 0 ) {...
阅读全文
摘要:题目:问n个节点构成完全对称的树有多少种方法。因为树是完全对称的,所以它的子树也是完全对称的。对于每个树,拿出一个根节点,枚举剩下的节点能拆分成多少个子树。#include #include #include #include #define LL long long intusing namespace std;const int MAXN = 1010;const LL MOD = 1e9 + 7;LL dp[MAXN];int main(){ dp[1] = 1; for ( int i = 2; i <= 1000; ++i ) { int v = i ...
阅读全文
摘要:这个……真心看不出来是个DP,我在树状数组的康庄大道上欢快的奔跑了一下午……看了题解才发现错的有多离谱。参考:http://www.cnblogs.com/kuangbin/archive/2012/11/11/2765329.html#include #include #include #include #define LL long long intusing namespace std;const int MAXN = 1000100;int val[MAXN];int pos[MAXN];int cnt[MAXN];int diff[MAXN];bool vis[MAXN];LL dp
阅读全文
摘要:题意:给你两个串A,B,问一个串长为M+N且包含A和B且恰好包含M个R的字符串有多少种组合方式,所有字符串中均只含有字符L和R。dp[i][j][k][S]表示串长为i,有j个R,在自动机中的状态为k,包含AB的状态为S的方案个数。PS1.之前用long long int超时了两次PS2.把行列搞错了WA了几次#include #include #include #include //#define LL long long intusing namespace std;const int MAX_NODE = 1210;const int CHILD_NUM = 2;const int MA
阅读全文
摘要:参考了:http://www.cnblogs.com/zhsl/archive/2013/08/10/3250755.htmlhttp://blog.csdn.net/chaobaimingtian/article/details/9852761题意:一个有n个节点的树,每个节点存有一份独一无二的信息,要求用最小的步数,把每个节点的信息共享给所有的节点。一个节点把自己所包含的所有信息传递给相邻的一个节点为一步。题目不是求最小的步数,而是问最小的步数下,信息传递的方法有多少种。分析:最小步数:所有节点把信息传给同一个节点,再由这个节点传给其他节点。因此最小步数为树边数的2倍,即2*(n-1)。我
阅读全文
摘要:参考了官方题解给的方法:对于处理循环,官方给了一种很巧妙的方法:#include #include #include #define LL long long intconst int MAXN = 50010;const int MAXMOD = 210;int N, K;int dp[MAXN][MAXMOD];int val[MAXN];int fac[MAXN 0; --i ) { sum = ( val[i] * fac[totL] + sum ) % K; totL += len[ val[i] ]; ...
阅读全文
摘要:跟矩阵链乘同类型的题……输出用%llu不是%I64u……几组数据:141+2*4+3*4+5*00*5*6+7*3+23+0+6+7+0+44*5+7*1*1+12*0+3*4*0+5*6+7+81+2+3*1+2*1+00+2*2+3*0+48*9*0+22*0+1+0*32*0*3+7+1*0*31+3*0*5+21+1+1+1+12*1+1+2*1+2*1+61*2*4*0*6*3#include #include #include #include #include #define LL unsigned long long intusing namespace std;const i
阅读全文
摘要:两次DFS求树直径方法见 这里。这里的直径是指最长链包含的节点个数,而上一题是指最长链的路径权值之和,注意区分。K R: ans = R − 1 + ( K − R ) ∗ 2; 1 #include 2 #include 3 #include 4 #include 5 6 using namespace std; 7 8 const int MAXN = 100010; 9 10 struct node 11 { 12 int v; 13 int next; 14 }; 15 16 int N, Q, EdgeN; 17 int head...
阅读全文
摘要:一个比较经典的题型,两次DFS求树上每个点的最远端距离。参考这里:http://hi.baidu.com/oi_pkqs90/item/914e951c41e7d0ccbf904252dp[i][0]表示最远端在以 i 为根的子树中的最长长度,dp[i][1]记录最远端在以i为根的子树中的次长长度,dp[i][2]表示最远端不在以 i 为根的子树中的最长长度。答案即为max( dp[i][0], dp[i][2] );dp[i][0]和dp[i][1]可以通过一次DFS得到。再看dp[i][2], 设fa[i]为节点 i 的父节点: dp[i][2] = max( dp[ fa[i] ][2]
阅读全文
摘要:感觉不是很好写的一道状态压缩。dp[i][j][k]表示第 i 行状态为k,第i - 1行状态为 j,具体细节见代码。内存卡的很死,要用滚动数组。还有一个比较坑爹的地方是它在输入蛋糕的时候中间可能会出现空行,一开始我用getchar()读,连第一组数据都过不去,后来改成scanf( "%s", str )才过……错了好多次。 1 #include 2 #include 3 #include 4 #include 5 6 using namespace std; 7 8 const int MAXN = 520; 9 const int INF = 1 0 &&
阅读全文
摘要:i 表示节点 i ,j=0表示不选择其父节点,j=1表示选择其父节点。f 为其父节点。取 每个节点选择/不选择 两者中较小的那个。一组数据:151 21 31 41 1010 910 1112 1012 1410 1313 154 55 74 66 8答案是6 1 #include 2 #include 3 #include 4 #include 5 #include 6 7 using namespace std; 8 9 const int MAXN = 100010;10 11 vector adj[MAXN];12 bool vis[MAXN][2];13 int d[M...
阅读全文
摘要:枚举每个位置,求以num[i]为起点的最长不下降子序列和以num[i]为结尾的最长不递增子序列。并且把相同值的个数统计一下,最后要减去算重复了的。比如:194 4 2 2 2 3 3 3 7#include #include #include using namespace std;const int MAXN = 100000 + 10;int n;int num[MAXN];int stack1[MAXN];int stack2[MAXN];int dp1[MAXN];int dp2[MAXN];int same1[MAXN];int same2[MAXN];void DP( int *s
阅读全文
摘要:跟 UVa1474 - Evacuation Plan 一个题,但是在杭电上能交过,在UVa上交不过……不知道哪里有问题……将施工队位置和避难所位置排序。dp[i][j] 代表前 i 个避难所收留前 j 个施工队。dp[i][j] = min( dp[i - 1][j - 1], dp[i][j - 1] ) + abs( b[i] - a[j] );内存卡的比较死,要用滚动数组,并且记录路径的path[i][j]只能用bool型。MLE了四五次OTL…… 1 #include 2 #include 3 #include 4 #include 5 6 #define LL...
阅读全文
摘要:一开始读漏了很多细节,用递推写死活跑不出样例。把题目中的细节列一下吧,状态方程很好推,改成记忆化搜索之后代码也很清晰。1.蜜蜂需要到最高的塔去,最高的塔可能不止一个,抵达任意一个即可。2.蜜蜂每次只能到达相邻的塔,满足的条件为横向移动距离 2 #include 3 #include 4 #include 5 6 using namespace std; 7 8 const int MAXN = 60; 9 const int INF = 1 = addr - W && j > 0; --j ) 41 { 42 res = min( res, D...
阅读全文
摘要:同 HDU 2836只不过改成了求最长子串。DP+线段树单点修改+区间查最值。 1 #include 2 #include 3 #include 4 #include 5 6 #define lson l, m, rt > 1;35 if ( L > 1;47 48 int res = 0;49 if ( L m ) res = max( res, Query( L, R, rson ) );51 52 return res;53 }54 55 int main()56 {57 while ( ~scanf( "%d%d", &n, &d ...
阅读全文
摘要:题意:给你一个序列,问相邻两数高度差绝对值小于等于H的子序列有多少个。dp[i]表示以i为结尾的子序列有多少,易知状态转移方程为:dp[i] = sum( dp[j] ) + 1;( abs( height[i] - height[j] ) 2 #include 3 #include 4 #include 5 6 using namespace std; 7 8 const int MAXN = 100100; 9 const int MOD = 9901;10 11 int dp[MAXN];12 int height[MAXN];13 int num[MAXN];14 int ...
阅读全文
摘要:水动规= = 1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 5 const int MAXN = 10010; 6 const char dic[26][10] = 7 { 8 ".-", "-...", "-.-.", "-..", 9 ".", "..-.", "--.", "....",10 "..&qu
阅读全文
摘要:dp[k][i][j]表示第k步左脚在位置 i,右脚在位置 j 状态时的最小能量消耗.dp[k][i][j] = min( dp[ k - 1 ][x][j] + cost[x][ step[k] ], dp[ k - 1 ][i][x] + cost[x][ step[k] ] );这题很坑爹的没有数据范围,数组我随便开的,居然1Y了…… 1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <algorithm> 5 6 using namespace
阅读全文
摘要:区间DP,刘汝佳黑书p113例题 1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <algorithm> 5 6 using namespace std; 7 8 const int MAXN = 210; 9 const int INF = 1 << 30;10 11 char str[MAXN];12 int dp[MAXN][MAXN];13 int path[MAXN][MAXN];14 bool vis[MAXN][MAXN];
阅读全文
摘要:S表示已用骰子的集合。dp[S][i][j]表示在当前集合下,最上面那个骰子为 i ,底面编号为 j 时所能得到的最大和, max[i][j] 表示骰子 i 以 j 为底时侧面的最大值,dice[i][j]表示 i 骰子 j 面的编号。dp[S][i][j] = max{ dp[ S ^ ( 1 << i ) ][k][m]+max[i][j] };k∈(S ^ ( 1 << i ) ), dice[k][5 - m]==dice[i][j]。为了方便判断相对的面,存储时处理一下,使得相对的面存储在编号加和为5的位置中。即如果 a, b 面相对,则 a + b = 5
阅读全文