??xml version="1.0" encoding="utf-8" standalone="yes"?>无码精品久久久久久人妻中字
,国产成人精品三上悠亚久久,亚洲日本久久久午夜精品http://m.shnenglu.com/Climber-pI/archive/2011/08/05/152580.htmlClimber.pIClimber.pIFri, 05 Aug 2011 12:51:00 GMThttp://m.shnenglu.com/Climber-pI/archive/2011/08/05/152580.htmlhttp://m.shnenglu.com/Climber-pI/comments/152580.htmlhttp://m.shnenglu.com/Climber-pI/archive/2011/08/05/152580.html#Feedback0http://m.shnenglu.com/Climber-pI/comments/commentRss/152580.htmlhttp://m.shnenglu.com/Climber-pI/services/trackbacks/152580.html7.26
最长公共子序列lcs, O(N^2)
f[i][j] = max{f[i-1][j], f[i][j-1], f[i-1][j-1]+1(if A_i==B_j)}
初始化f[_][0] = f[0][_] = 0
7.27
~辑距离edit, O(N^2)
f[i][j] = min(f[i][j-1] + 1, f[i-1][j] + 1, f[i-1][j-1] + !(A_i==A_j))
初始化f[i][0] = f[0][i] = i
*参考[q里]http://en.wikipedia.org/wiki/Levenshtein_distance
*状态{U过E中, 充分不一定最? 必要才是最? 事实上边界条件L其具体意?br />*[相关]http://www.matrix67.com/blog/archives/333
最短回文串palindrome[poj 1159], O(N^2)
1.套用lcs, O(N^2), 60
f[i][j] = max{f[i-1][j], f[i][j-1], f[i-1][j-1]+1(if A_i==B_j)}
初始化f[_][0] = f[0][_] = 0, n - f[n][n]即ؓ{案
*利用滚动数组优化, I间复杂度O(N), 80
*关键语句k = 1 - k, 注意在内层@环外
2.套用edit, O(N^2), 30
f[i][j] = min(f[i][j-1] + 1, f[i-1][j] + 1, f[i-1][j-1] + 2*!(A_i==A_j))?br />初始化f[i][0] = f[0][i] = i, f[n][n]/2即ؓ{案
3.O(N^2), 30
f[i,j]表示Ai..Aj变ؓ回文串的最代P?br />f[i][j] = f[i+1][j-1] (若Ai=Aj)
min(f[i+1][j],f[i][j-1])+1 Q若Ai<>AjQ?br />4.利用位运优?br />http://www.csse.monash.edu.au/~lloyd/tildeStrings/Alignment/86.IPL.html
币Ncoin[完全背包], O(N^2)
f[j] = min(f[j], f[j-c[i]]+1)
初始化f[0] = 0, f[1..T] = INT_MAX
*注意下标非零 ?INT_MAX的溢?/p>
7.28
导弹拦截missile[LIS + 二分], O(NlogN)
(1)二分查找O(logn)
f[i] = max(f[j] + 1) (j < i)
d[i] = min(f[k]) (f[k] == i)
易知d[i]单调, 因而可以利用二分查N低复杂度, i最大值即LIS长度为t, 那么
i) f[i-1] < k <= f[i] (1 <= i <= t)
ii) 若k > Lf[], 则f[t+1] = k;
iii) ?k, 则f[1] = k;
*例子参见[q里]http://www.matrix67.com/blog/archives/112
[代码实现]
//情况ii和iii需要单独处?br />x = 1; y = t;
while (x <= y){
m = (x + y)/2;
if (f[m-1] < k && k <= f[m]) break;//对于最长上升子序列和最长不下降子序列判定条件不???
//if (f[m-1] < k && k <= f[m]) return m;
else if (k > f[m]) x = m + 1Q?br /> else y = m - 1;
//return x;
}
*利用注释, 可以避免Ҏ况ii的单独处理LIS的方? 记录Ҏ需要用pre数组, 范例不知???
*需要注意的? f数组l出的ƈ非是一?br />(2)最链划分 = 最长反N?关于偏序? 参见《组合数学》P73)
[Dilworth定理]令(X,≤Q是一个有限偏序集Qƈ令m是反铄最大的大小。则X可以被划分成m个但不能再少的链?/p>
最长不下降子序列lis[LIS + 二分], O(NlogN)
对[1..k-1][k+1..n]两个序列分别q行一ơLIS卛_.
*问题的关键之处在于第一ơ理解不d和Qw? 以及对于困难E度的不合理估计.
7.29
加分二叉树tree[区间 + 记录Ҏ], O(N^3), 20min
f[i][j] = max(f[i][k-1] * f[k+1][j] + A[k]) (i <= k <= j)
初始化f[i][i] = A[i], f[i+1][i] = 1
[记录Ҏ]pa[i][j] = k, 递归卛_, [边界]pa[i][j] == i 或?j, 以及i == j的情?/p>
整数划分separate[区间 + 记录Ҏ], O(N^3), 2h
f[k][i]表示序列1..i分成kD늚最大?br />f[k][i] = max(f[k-1][j-1] * A[j][i])
pa[k][i] = j
初始化f[1][_] = A[1][_], 其他f[][] = -1
*注意{号情况同样需要更?br />if (f[K][i] <= f[K-1][k-1] * A[k][i])
f[K][i] = f[K-1][k-1] * A[k][i],
pa[K][i] = k; //记录Ҏ
*[pa[k][i], i]加入{案, 递归[1, pa[k][i]-1], [边界] k == 0
*在Win下用long long占位Wؓ"%I64d", 在Linux下占位符?%lld", 考试中利?lt;fstream>避开占位W问?/p>
凸多边Ş的三角剖分division[区间]
f[i][j] = max{f[i][k] + f[k][j] + w(i, j, k)} (i < k < j)
初始?<=i-j<=2的f只ؓ0, 其他?1
*表达式中同时出现long long和int的话, 会自动{换ؓint
*只过?个点, 原因不知 -> 数据错误, 最?个点output一?br />*各种牛们普遍指出没有考虑i>j的情?-> 怎么???
机器分配machine[区间], O(N^3)
f[i][j] = max(f[i-1][k] + A[i][j-k]) (0 <= k <= j)
初始化f[][] = 0, f[i][j] = max(f[i][j], A[i][j])
*注意读题"Wi个公司分配j台机器的盈利", 不是分配Wj台机器的盈利
装箱问题box[分组背包], O(N^2), 30min
f[i][j] = max{f[i-1][j], f[i-1][j-c[i][k]] + w[i][k]}
初始化f[][] = 0
*读题时注意变量的对应关系
*注意本题中背包不一定要装满
7.31
最长前~prefix[判断性dp], O(kN), 70min
f[i] |= f[i - len[j]] & check(i - len[j] + 1, j) (1 <= i,j <= n)
初始化f[] = 0, check(x,y)表示M[x,x+len[y]-1]和前~y是否相同
*弄错j和len[j], 注意方程的字母指? 以及实现中的字符指针位置, 注意静态查错[30min]
*[8.4优化]把check函数直接写在循环? 如果f[i] == 1直接break -> 依旧时三个?br />*[8.5优化]i的上限ؓmin(n, ans + 20), 更新f[i]的时候记录ans卛_ -> AC
8.1
关键子工Eproject[DAG最长\], 70min
f[i] = max(f[j] + w[i]) (G[j][i] == 1)
初始化f[i] = w[i]
记录Ҏ, 利用f[i] == w[i] + f[j] (G[j][i] == 1)
*利用定义求拓扑排? 输出Ҏ可以利用队列递归转化P? 无解情况用flag标记(inq数组表示是否在队列中)
*在纸上写出关键部分的代码, 两倍行?比如递推或者记忆化函数, 输出Ҏ的函?
8.2
三角蛋糕trigon[坐标dp], 130min
[做法1](需保留I格)
f_[i][j]表示?i, j)为顶点的Rt△的最大边?br />对于倒三角Ş, 自右向左 f1[i][j] = min(f1[i+1][j], f1[i][j+1]) + 1
自左向右 f2[i][j] = min(f2[i+1][j], f2[i][j-1]) + 1
对于正三角Ş, 自右向左 f1[i][j] = min(f1[i-1][j], f1[i][j+1]) + 1
自左向右 f2[i][j] = min(f2[i-1][j], f2[i][j-1]) + 1
初始? f[][] = 0(A[][] = '#'), f[][] = 1(A[][] = '-'); min(f1[i][j], f2[i][j])^2的最大值即为答?br />[做法2](不需保留I格)
f[i][j]表示?i, j)为顶点的△的最大高?br />对于倒三角Ş, f[i][j] = min(f[i-1][j], f[i-1][j+1], f[i-1][j+2]) + 1
对于正三角Ş, f[i][j] = min(f[i+1][j], f[i+1][j-1], f[i+1][j-2]) + 1
初始? f[][] = 0(A[][] = '#'), f[][] = 1(A[][] = '-'); min(f[i][j])^2即ؓ{案
*输入需保留I格, 卡了30min(排除ASCII?0?3的字W即?
*没有考虑正方? 大约2h时对照std发现
*有两个点数据错误, 对照std后发现std仅当横坐标ؓ奇数是考虑倒三角Ş, 横坐标ؓ偶数时考虑正三角Ş, 而题目中无此限制
*学习利用批处理对拍的写法
@echo off
:again
gen
trigon
trigon_me
fc trigon.out trigon_me.out > nul
if not errorlevel 1 goto again
选课course[树Şdp]
[做法1]多叉转二?br />f[i][j]表示以i为根节点的树? 选择j门课
f[i][j] = max(f[i.r][j], f[i.l][k] + f[i.r][j-k-1] + i.v) (0<=k<j)
初始化f[][] = 0
*无法记录Ҏ -> gXX表示比较困难
[做法2]泛化物品
??? -> x?-> 需要学?/p>
通向自由的钥匙key[树Şdp], 150min, zoj 2280
f[i][j]表示以i为根节点的数, p能量为j时可以拿到的最多的钥匙?br />f[i][j] = max(f[i.r][j], f[i.l][k] + f[i.r][j-k-i.c] + i.v) (o<=k<=j-i.c)
初始化f[][] = -1, 边界处理f[i][j] = 0(i<=0 || j<0)
*记录各点L矩阵, 利用dfs构造树(注意处理后取消邻?, q多叉{二叉 -> 30min
*对于f[i.r][j]不必在记忆化搜烦函数中遍历所有兄? 只遍历最q的卛_
*注意读题, 出发点ؓ1, i.c和i.v非负 -> 1.5min
*注意静态查? 如记忆化搜烦中dp(i, j)打成f(i, j)的情?br />*觉得比较晕的时候等一下再调题, 可以先干点别? q样可以减少旉的浪?/p>
警卫安排security[树Şdp], 100min
[状态]
f[i][0]表示以i为根节点, q在i安排警卫的最花?br />f[i][1]表示以i为根节点, i的父节点已安排警卫的最花?br />f[i][2]表示以i为根节点, i的子节点已安排警卫的最花?br />[方程]
f[i][0] = Σmin(f[i.son][0], f[i.son][1], f[i.son][2]) + i.v
f[i][1] = Σmin{f[i.som][0], f[i.son][2]} (i不是树的根节?
f[i][2] = min{Σmin{f[i.son][0], f[i.son][2]}(i.son != k) + f[k = i.son][0]}
[初始化]
对于叶节? f[i][0] = i.v, f[i][1] = 0, f[i][2] = i.v
对于其他? f[][] = -1
*对于根节点的L, 利用prev[i]记录i的前? ?prev[i], 则i为树?br />*l合批处理和makedata以及范围暴力程? 可以有效地避免各U错误及极端情况 -> 需要学习搜?br />*对于q类题目, 思考的关键在于分类写出方程, q注意方E的边界条g(cM:tyvj 没有上司的舞?
*对于树Şdp, 存在两种cd; 一U是对于加权路径长度限制, 另一U则是求加权最?/p>
8.4
青蛙的烦恼frog[区间dp]
初看是最生成树问题, 但是此题有几个特别的性质:
1.?可叶ؓL, l点不定
2.遍历荷叶的最短\径是一条链
3.题目l出的坐标顺序是一个顺旉方向的多边Ş
4.最短\径不怺(M个四边Ş, 利用三角形性质可以观察?
Ҏ性质1?, Ҏ得出O(N^3)的方E? 很明显会时
f[i][j] = min(f[k][j-1] + d[i][k]) (i!=k)
-f[i][j]表示以iv? 长度为j的最短\? 初始化f[i][1] = 0
q而考虑性质3?, 因而对于点1, 只能选择盔R的点2和n, 可以得到O(N^2)的方E?br />f[i][j][0] = min{f[i+1][j-1][0] + d[i][i+1], f[i+1][j-1][1] + d[i][i+j-1]}
f[i][j][1] = min{f[i][j-1][1] + d[i+j-1][i+j-2], f[i][j-1][1] + d[i+j-1][i]}
-f[i][j][0]表示以iv? 长度为j的最短\? f[i][j][1]表示以i为终? 长度为j的最短\? 初始化f[][1][] = 0
-一个实C的小优化, 保证d[i][j](i<j)
*注意静态查? 区别变量? 思考算法的q程应该长于调试的过E?br />*修正了测试点6
火Rq站train[U性dp], 70min
1.M <= 3 -> 可以分类讨论
2.只存在一条轨? M只能军_轨道的长?-> 如果同时在轨道中, i在j前的必要条g是i.s<=j.s和i.t<=j.t
3.站工作人员可以L安排q些火Rq站的先后排?-> 记忆化搜?br />4.站允许几辆火R同时q站或出?-> 所有条仉可取{号
M = 1, f[i] = max(f[j] + 1) (i.t <= j.s)
M = 2, f[i][j] = max(f[j][k] + 1) (i.t <= k.s)
M = 3, f[i][j][k] = max(f[j][k][l] + 1) (i.t <= l.s)
初始化f = 0, 利用vis记录是否计算q? 各下标互不相{?br />*枚Dq程中注意剪? 利用i!=j和i.s<=j.s,i.t<=j.t逐层处理卛_
*[读题]明确要求的是什? 存在哪些条g, 写list
*[未验证]先对以进站时间ؓW一关键? 出站旉为第二关键字q行快排, 然后直接递推, 下标满i < j < k < l
快餐问题meal[资源分配(不妨认ؓ是背?dp + 贪心优化] -> cM, usaco 3.4.4 rocker
f[k][i][j]表示k条生产线生i个汉? j个薯条时生饮料的最大? p[k][i][j]表示Wk条生产线, 其他?
f[k][i][j] = max{f[k][i-ki][j-kj] + p[k][i][j]}
sum[i] = sum[i-1] + A[i]
初始化f[1][i][j] = p[1][i][j], f[2..n][i][j] = -1, 复杂度O(N*100^4)
几个优化
1.注意到每U物品L于100, 最大量的上限是lim = min(100/a, 100/b, 100/c, sum[n]/(a*p1+b*p2+c*p3))
2.Z避免数组界, i的上限是min(lim*a, sum[n]/p1), j的上限min(lim*b, (A[k] - i*p1)/p2);
ki的上限min(i, A[k]/p1), kj的上限min(j, (A[k] - ki*p1)/p2) -> 对于逗号双, 其实是ki*p1+kj*p2<=A[k]
3.程序中的min/max用if语句替代
4.对于每一套生产线, 量成套生
[反例]
1 1 1
2 3 7
3
15 16 17
贪心可得最大gؓ3, 实际?5 = 7 + 3 + 3 + 2, 16 = 7 + 3 + 2 + 2 + 2, 17 = 7 + 7 + 3, 最大gؓ4;
利用优化1?可以q?个测试点, 优化3可以q一步优化时间常? 利用优化4可以q?个测试点
ACE序参见[此文]http://hi.baidu.com/zijingningmeng/blog/item/2761617e2afe7ae32e73b3b3.html
*调试q程中的主要问题是边界溢?没有区分是否计算q?, 变量名写?br />*|上有说法表C去掉每U物品的件数限制? 题目变成|络?-> gXX证伪
*比赛的话, 不妨数?n<5)DP, 大数?n>=5)贪心, q样应该可以得到过一半的分数
卡R更新问题truck, O(N^2), 1h
f[i][k]表示Wiq某车已使用了kq?br />f[i][k] = max{f(i+1, 1) + R[0] - U[0] - C[k], f(i+1, k+1) + R[k] - U[k]}
初始化f[][] = -1, 边界条gf[i][k] = 0(i>N,k>K), 利用记忆化搜索实?br />记录Ҏ利用bool型数lprev[i][j][k]记录是否购买新R, 递归卛_
*可能不换新?br />*利用样例构造树, 写出状态即可得到方E?br />*试?存在{hҎ, 已修正数?可能需要Special Judge)
*f[i][j][k]中i和k可以唯一定状? 因而可以去掉中?l?/p>
选课course[树Şdp + 记录Ҏ], 多叉转二叉实?br />f[i][j]表示以i为根节点的树? 选择j门课
f[i][j] = max(f[i.r][j], f[i.l][k] + f[i.r][j-k-1] + i.v) (0<=k<j)
初始化f[][] = 0
[记录Ҏ]
利用print(i, j)递归, vis[i][j]表示是否已遍? [边界]i∈[1, m], j∈[1, n]
right[i][j]表示f[i][j]是否{于f[i.r][j]
prev[i][j] = k表示f[i][j]由f[i.l][k],f[i.r][j-k-1]推得, q时需记录p[i] = 1
?到n判断p[i]直接输出卛_.
8.5
q场铺砖问题floor[状压dp], 2h
f[i][S] = Σf[i-1][S'] (S由S'推得)
初始化f[1][0] = 1, f[h+1][0]即ؓ{案
对于每个f[i-1][S']利用dfs(当前行i, 当前行状态s1, 下一行状态s2, 当前行指针k)LS
if(!(s2 & 1<<k) && !(s2 & 1<<(k+1)))
dp(i, s1, s2, k + 2);//存在q箋两个IZ, x?br />dp(i, s1, s2 ^ (1<<(k)), k + 1);//对当前位取反, 即竖?br />利用int保存每一位的摆放方式, 1表示当前行被上一行占? 0表示当前行未被占?br />[边界]k = 0, 递归q程中k > w则退?/p>
木地板floor2[状压dp]
f[i][S] = Σf[i-1][S'] (S由S'推得)
初始化f[1][0] = 1, f[h+1][0]即ؓ{案
*实现无能, 最l放?-> 我应该去学位q算优化BFS -_-
*鱼牛《状态压~》理解不? NOI导刊朱全民文章code不全.
*耗时最长的题目往往不是表面上的N, 而是那些被简单估计的N

]]>- Problem List (7.13 ~ 7.20)http://m.shnenglu.com/Climber-pI/archive/2011/07/21/151551.htmlClimber.pIClimber.pIThu, 21 Jul 2011 07:55:00 GMThttp://m.shnenglu.com/Climber-pI/archive/2011/07/21/151551.htmlhttp://m.shnenglu.com/Climber-pI/comments/151551.htmlhttp://m.shnenglu.com/Climber-pI/archive/2011/07/21/151551.html#Feedback0http://m.shnenglu.com/Climber-pI/comments/commentRss/151551.htmlhttp://m.shnenglu.com/Climber-pI/services/trackbacks/151551.html7.13
p1057 金明的预方案[分组背包], 1.5h
f[v] = max{f[v], f[v - c[i][j]] + w[i][j]}
*注意读题Q主件的~号和物品编L同,q里调了1h
*注意逗号的?br />
@Ural p1018 Binary Apple Tree[树Ş], 1.5h{大量参考题解}
f[i][j] = max(f[tree[i].l][k] + f[tree[i].r][j-k-1] + tree[i].v)
*初始化中使用-1标记未计?避免重复0)
*递归建树 -> L儿子的过E可利用L表优化[未验证]
*记忆化搜索f[t][q]初始化ؓ0, 根节点值最后计? 注意Ҏ情况0
*特别注意, 把题目中?Ҏ 转换?Ҏ, 以及q的相兛_?br />
7.15
#p1051 选课[树ŞDP], 1.5h
f[i][j] = f[tree[i].r][j] (左子树空)
f[tree[i].l][k]+f[tree[i].r][j-k-1]+tree[i].v (左子树非I?
*多叉树{二叉?-> 左儿? 叛_?br />if (!left[a]) tree[a].l = i;
else tree[left[a]].r = i;
left[a] = i;
**记忆化搜索过Eؓ什么不能直接返回int -> 实验证实会引起错? 原因不明 -> 盲目合ƈ语句所?br /> if (f[i][j] || i == 0 || j <= 0) return 0;
应ؓ
if (i == 0 || j <= 0) return 0;
if (f[i][j]) return f[i][j] ;
-> 合ƈ此类控制边界语句应注意返回?br />**泛化背包做法 http://archive.cnblogs.com/a/2091585/
p1087 sumsets[完全背包+l计Ҏ数], 60min
f[i][j] = f[i-1][j] + f[i][j-c[i]] (f[0][0] = 1)
一开始盲目列表找递推? 试无果. 后发现题目本意即完全背包问题, 2^k是物? 实现时注意降l?
*l计ҎL问题递推式中max改ؓ+, 注意f[0] = 1
*此类问题注意高精度的实现 或?mod(注意题目中要? 如本?位精?
*另一U方E?f[i] = f[i-1] (i=2k+1) -> 已通过观察得到
f[i-1] + f[i/2](i=2k) -> 动机是什?
p1079 数字三角?[坐标DP], 30min
f[i][j] = max(f[i+1][j], f[i+1][j+1]) + A[i][j] (0 < j <= i <= n/2)
通过分析可知, 指定?n/2, n/2)?i, i)必取, 而其后和一般数字三角做法相? l点为f[n/2][n/2]
故最l答?#931;f(i,i)_(0 < i < n/2) + f[n/2][n/2]
*坐标问题注意分析L和终点的要求
p1084 数字三角?[坐标DP], 10min
(x, y)? f1[i][j] = max(f1[i-1][j-1], f1[i-1][j]) + A[i][j] (0 < j <= i <= x)
(x, y)? f2[i][j] = max(f2[i+1][j], f2[i+1][j+1]) + A[i][j]
分析可知, (x, y)前顺? 指定l点?x, y), L必然?1, 1), (x, y)后逆推, 指定l点?x, y)
故最l答案ؓf1[x][y] + f2[x][y] - A[x][y]
p1076 数字三角?[判定性DP], 30min
f[i][j][(k+A[i][j])%100] = f[i+1][j][k] | f[i+1][j+1][k]
通过增加l度转化为判定性问? ׃取模所以k的顺序不定, 因而用坐标来控刉?br />
7.16
#p1048 田忌赛马[贪心 + DP], 1.5h
1.O(N + NlogN), [题解来自|络]思想是这L, 先把各组马的速度从大到小排序, 然后用田忌的马顺序与齐威王的马比?br />ifQ田忌的马快Q比较下一寚wQ?br />else ifQ田忌的马慢Q用田忌最慢的马和齐威王的q匹马赛
else{
从未q行比赛的速度的马开始从后往前比
ifQ田忌的马快Q?nbsp; //q里是必ȝQ否则如果是90 73 71 ?90 70 70 Q那么没有这个是
l箋往前比 //2-1,有了的话是2+0Q非帔R?br /> else 用这匚w和刚才跑q的齐威王的马比
//M原则是如果q匹马不能赢Q就让他和比他快很多的马比,q样保持速度较快的马
}
*while循环条g, f1 <= r1
2.O(N^2 + NlogN), 来自:http://hi.baidu.com/lyltim/blog/item/57fccd1153ea851eb9127ba9.html
[贪心分析]
1、如果田忌剩下的马中最强的马都赢不了齐王剩下的最强的马,那么应该用最差的一匚w去输l齐王最强的马?br />2、如果田忌剩下的马中最强的马可以赢齐王剩下的最强的马,那就用这匚w去赢齐王剩下的最强的马?
3、如果田忌剩下的马中最强的马和齐王剩下的最强的马打q的话,可以选择打^或者用最差的马输掉比赛?br />[DP做法]
f[i,j]=max{f[i-1,j]+g[n-(i-j)+1,i],f[i-1,j-1]+g[j,i]}
其中g[i,j]表示田忌的马和齐王的马分别按照由强到q序排序之后Q田忌的Wi匚w和齐王的Wj匚w赛跑所能取得的盈利
#p1402 乌龟[路径DP], 1.5h
f[i][j][k][l] = max(f[i-1][j][k][l], f[i][j-1][k][l], f[i][j][k-1][l], f[i][j][k][l-1]) + A[i+2j+3k+4l+1]
以卡片数为阶D? 状态f[i][j][k][l]表示q剩下每U牌各多张时得到的最大? 注意起始位置
*卡了1h因ؓ?5的过沛_08的传U条限制思维, 认ؓ以所在位|ؓ阶段, 惛_I间降维
*[降维条g]状态各l度存在{量关系, 因而可减少旉复杂? 但是不能改变I间复杂?br />
#p1052 没有上司的舞会[树ŞDP], 1.5h
f[i][0] = ∑max{f[j][0], f[j][1]} (j∈i.son), i不参?br />f[i][1] = ∑f[j][0] + tree[i].v (j∈i.son), i参加
[边界]若i为叶节点, f[i][0] = 0, f[i][1] = tree[i].v
前半个小时写完了多叉转二? 证明了left[]的必要?
*状态设计问? 没有区分i参加和不参加的情? q认为f[i]由f[j](不取i, j是i的儿?和f[k](取i, k是i的孙?推得
*叶节点的初始? 对于f[i][]求和而非取最大? 选取根节点而非叶节?需要两个数l映?
*׃30min时方E考虑不周, D多次修正, 因而卡?h. 务必要先写出正确方程.
7.18
p1134 CCR的中考之考前计划[模拟], 50min
语文? 题目描述问题很大, 费?.5h, google了一个std之后得到正确题意. 题目是类似beads的模拟题, 环从某处打? 使得两端U目cd相同的天数最?L相同U目的条件A[j+1] = 'w' || A[j+1] = A[i].
*环状问题的处理方? 2n-1, 在本题中双方向同时进行不?n-2
#p1088 treat[区间DP], 20min
f[i][j] = max{f[i+1][j] + A[i] * (n+i-j), f[i][j-1] + A[j] * (n+i-j)} (0 < i < j <= n)
f[i][j]表示[i, j]未取时的最大? 初始化f[i][j] = A[i] * n, 以长度l为阶D? ?j = i+l-1
*考虑Wkơ取? k = n - (i-j+1) + 1(包括q次), 昨天没想到这点卡了很?br />*在网上找C另外一U设|状态的Ҏ, 设f[i][j]是取i个数, 左边取j? 方程Q?br />f[i][j] = max(f[i - 1][j - 1] + i * A[j], f[i - 1][j] + i * A[n - (i - 1 - j)])
-> 猜想动机: 存在{式 ?+ ?= L, 状态的讄都是Z描述着三个?
agirnet[Krusal], 20min
复习q查集实现的Krusal
p1307 联络员[Krusal],50min
必选边先用set[find(e[i].u)] = find(e[i].v)合ƈ, q记录权? 然后按一般的Krusal做即?
*使用stdlib.h的qsort间接排序p|, 原因不知(20min)
*注意此时k++不能q入下一行语句中, 否则++k和kg同导致输入错?
++k,
scanf("%d%d%d", &must[k].u, &must[k].v, &must[k].w);
7.20
p1113 族密码[LIS模型], 40min, 6WA
f[i] = max{f[j] + 1} (A[j]为A[i]前缀, 1 <= j < i)
*注意最大g一定在f[n]? 需要对f[1] -> f[n]q行循环? 卡了30min
p1187 飞侠的游园Ҏ[0/1背包], 15min
f[i][j] = max(f[i-1][j], f[i-1][j - c[i]] + w[i])
存在可能未装满的情况, 故@环检查f[n][]卛_
#p1190 U木城堡[背包DP], 1.5h, 6WA
f[k][j] = f[k][j - w[i]] (j - w[i] >= 0)
cM分组背包的做? 记录每组物品的所有可能? 若f[1..k][V]同时为true, 则V为最? 也可以在d? 循环查每l物品的可能?
*注意读题, 其是各U数据范? 不要重复dW二?!!
*d时注意MAXn+1, 留意-1的情? 昄{案不会过所有城堡的最高?而非最?.
*题目中ƈ没有按顺序取U木, 因而一开始打了模? 之后手贱去Google. 对于q类问题, 在提交后若发现则应l思? 此外不要l题目增加条?
**注意q类定各组物品所有可能值写??最优值写法的区别
*一l测试数?
5
87 76 65 54 32 21 23 -1
64 75 25 63 76 23 75 13 64 23 -1
09 78 76 46 32 45 23 -1
23 34 45 -1
12 34 23 -1
p1213 嵌套矩Ş[LIS模型/DAG最长\], 1h, 9WA
(1)f[i] = max(f[j] + 1) (rect[i]可嵌套rect[j])
*初始化f[] = 1; 初始化ؓ0, 输出+1会导致错? 原因不知.
-> 另一U写?by Ylen): f[0] = 0, f[] = INT_MAX;
*注意题目没有矩Ş间存在顺? 因而存在后效? 易知面积的矩Ş不会嵌套面积大的矩Ş, 因而以面积为关键字对rectq行间接排序.
(2)f[i] = max(f[j] + 1 | (i,j)∈G)
若rect[i]可嵌套rect[j], 则徏立一条从i到j的边, 求最长\卛_
]]> - Problem List (5.7)http://m.shnenglu.com/Climber-pI/archive/2011/05/07/145912.htmlClimber.pIClimber.pISat, 07 May 2011 12:26:00 GMThttp://m.shnenglu.com/Climber-pI/archive/2011/05/07/145912.htmlhttp://m.shnenglu.com/Climber-pI/comments/145912.htmlhttp://m.shnenglu.com/Climber-pI/archive/2011/05/07/145912.html#Feedback0http://m.shnenglu.com/Climber-pI/comments/commentRss/145912.htmlhttp://m.shnenglu.com/Climber-pI/services/trackbacks/145912.html5.7
p1004 滑雪[2d最长下降子序列]
无思\.
p1005 采药[?1背包], 调了1.5h
[spec,1d] f[j] = max{f[j], f[j - c[i]] + w[i]}, 能够有效避免f[i][j]中i的指代问?br>*2d写法L意f[i][j] = f[i-1][j]的g?br> for (i = 1; i <= n; i++)
for (j = T; j >= 1; j--)
if (j >= t[i])
f[i][j] = max(f[i - 1][j], f[i - 1][j - t[i]] + w[i]);
else f[i][j] = f[i - 1][j];
p1003 扑֕扑֕找GF[加强?1背包], 调了1h
读题分析后发现是0/1背包模型, 旉需要单独处?(一开始认记录路径, 其实不用q么ȝ)
f[m][r] = max{f[m][r], f[m - rmb[i]][r - rp[i]] + 1}
t[m][r] = max{t[m][r], f[m - rmb[i]][r - rp[i]] + time[i]}, 如果f[m]..和f[m-rmb[i]]..相等,注意更新t[m][r]
[补]写rocker的时候想CU方法,对于dpQ维度往往是需要表C的量数-1Q所以关于方E状态的表示可以从时间复杂度、空间复杂度、需要表C的量数l合考虑.此题中加上time的话Q显然爆旉Q然后从q个方向思考方E?
p1015 公\乘R[U性dp]
f[i] = max{f[i - k] + A[k]} (1 <= k <= 10)
p1011 传纸条[双线Edp + 旉降维]
注意读题, 题目中的来回{hZơ同时的单向q程
f[x1][y1][x2][y2] = max{f[x1-1][y1][x2-1][y2], f[x1-1][y1][x2][y2-1], f[x1][y1-1][x2][y2-1], f[x1][y1-1][x2-1][y2]}+A[x1][y1]+A[x2][y2]
注意每个数if and only if取一? f[x1][y1][x2][y2] -= A[x1][y1](x1=x2&&y1=y2)
p1014 乘法游戏[区间dp]
无思\

]]> - USACO 4.1.1 Nuggetshttp://m.shnenglu.com/Climber-pI/archive/2010/10/19/130467.htmlClimber.pIClimber.pITue, 19 Oct 2010 09:05:00 GMThttp://m.shnenglu.com/Climber-pI/archive/2010/10/19/130467.htmlhttp://m.shnenglu.com/Climber-pI/comments/130467.htmlhttp://m.shnenglu.com/Climber-pI/archive/2010/10/19/130467.html#Feedback0http://m.shnenglu.com/Climber-pI/comments/commentRss/130467.htmlhttp://m.shnenglu.com/Climber-pI/services/trackbacks/130467.html重启usaco.
抽象出模?可以发现是一个简单的完全背包问题,复杂度O(N^2+VN).需要考虑几种Ҏ情况:
(1)无解
当且仅当n个数中有一个数?.
(2)惟一?br>需要确定的是体Uv的最大?题解中是最大的两个数的最公倍数,E序中用最大数的^?证明Ҏ不知.
(3)无限?br>n个数不互?br>
1
/**//*
2
ID: liuyupa1
3
PROG: nuggets
4
LANG: C++
5
*/
6
#include<stdio.h>
7
int w[15] =
{0}, f[66000] =
{0};
8
int p[] =
{2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251};
9
void swap(int *x, int *y)
{
10
int k = *x; *x = *y; *y = k;
11
}
12
int max(int x, int y)
{
13
return x>y ? x : y;
14
}
15
int main()
{
16
FILE *fin, *fout;
17
fin = fopen("nuggets.in", "r");
18
fout = fopen("nuggets.out", "w");
19
int n, i, j;
20
fscanf(fin, "%d", &n);
21
for (i = 1; i <= n; i++) fscanf(fin, "%d", &w[i]);
22
for (j = 0; j < 54; j++)
{
23
int t = 0;
24
for (i = 1; i <= n; i++)
25
if (w[i] % p[j] == 0) t++;
26
if (t == n)
{
27
fprintf(fout, "0\n", p[j]);
28
return 0;
29
}
30
}
31
for (i = 1; i < n; i++)
32
for (j = i+1; j <= n; j++)
33
if (w[i] > w[j]) swap(&w[i], &w[j]);
34
if (w[1] == 1)
{
35
fprintf(fout, "0\n", p[j]);
36
return 0;
37
}
38
for (i = 1; i <= n; i++)
39
for (j = 0; j <= w[n]*w[n]; j++)
40
if (j-w[i] >= 0)
41
f[j] = max(f[j], f[j-w[i]]+w[i]);
42
i = w[n-1]*w[n];
43
while (i > -1 && f[i] == i) i--;
44
fprintf(fout, "%d\n", i);
45
return 0;
46
}
47

]]> - NOIp 2005 q河http://m.shnenglu.com/Climber-pI/archive/2010/10/08/129084.htmlClimber.pIClimber.pIFri, 08 Oct 2010 13:54:00 GMThttp://m.shnenglu.com/Climber-pI/archive/2010/10/08/129084.htmlhttp://m.shnenglu.com/Climber-pI/comments/129084.htmlhttp://m.shnenglu.com/Climber-pI/archive/2010/10/08/129084.html#Feedback1http://m.shnenglu.com/Climber-pI/comments/commentRss/129084.htmlhttp://m.shnenglu.com/Climber-pI/services/trackbacks/129084.htmlU性dpQ但是范围很变? = =
30%的方E很Ҏ惛_:
[状态] f[i]表示?到iҎ踩到的矛_? stone[i]表示iҎ无石?
[方程] f[i] = max{f[i-j] + stone[i]} (S<=j<=T)
[初始化] f[0] = 0, 其他赋gؓ无限?
在实现的时候需要把方程变化?f[i+j] = max{f[i] + stone[i+j]}Q不然在[1,S]会出现很诡异的结?
׃mq远于lQ整个序列上的石子非常稀?所以可以减状?但是目前Ҏq是有些不解.
某种思\是,石子间距大[1,2,..,9,10]=2520的逐次减至于2520.注意要在收尾增加0和l两个"矛_"Q这栯新的l较ؓ方便.
1
#include<stdio.h>
2
#include<iostream>
3
using namespace std;
4
#define MAXN 1000000;
5
bool L[200000] =
{0};
6
int f[200000] =
{0}, stone[110] =
{0};
7
int min(int x, int y)
{return x < y ? x : y;}
8
void swap(int x, int y)
{
9
int k = stone[x];
10
stone[x] = stone[y];
11
stone[y] = k;
12
}
13
int main()
{
14
int l, S, T, M, i, j;
15
scanf("%d%d%d%d", &l, &S, &T, &M);
16
for (i = 1; i <= M; i++) scanf("%d", &stone[i]);
17
stone[0] = 0;
18
for (i = 1; i < M; i++)
19
for (j = i+1; j <= M; j++)
20
if (stone[i] > stone[j]) swap(i, j);
21
stone[++M] = l;
22
for (i = 1; i <= M; i++)
{
23
while (stone[i] - stone[i-1] > 2520) stone[i] -= 2520;
24
if (i != M) L[stone[i]] = 1;
25
}
26
l = stone[M--];
27
for (i = 0; i <= l; i++) f[i] = MAXN; f[0] = 0;
28
for (i = 0; i < l; i++)
29
for (j = S; j <= T; j++)
{
30
int k = i+j;
31
if (i + j >= l) k = l;
32
f[k] = min(f[k], f[i]+L[i]);
33
}
34
printf("%d\n", f[l]);
35
}

]]> - NOIp 2003 加分二叉?/title>http://m.shnenglu.com/Climber-pI/archive/2010/10/05/128667.htmlClimber.pIClimber.pITue, 05 Oct 2010 03:10:00 GMThttp://m.shnenglu.com/Climber-pI/archive/2010/10/05/128667.htmlhttp://m.shnenglu.com/Climber-pI/comments/128667.htmlhttp://m.shnenglu.com/Climber-pI/archive/2010/10/05/128667.html#Feedback4http://m.shnenglu.com/Climber-pI/comments/commentRss/128667.htmlhttp://m.shnenglu.com/Climber-pI/services/trackbacks/128667.html形DPQ需要记录方案,q注意空树的情况.
[状态]f[i][j]从结点i到j的最大加分?/span>
[方程]f[i][j] = max{f[i][k-1]*f[k+1][j]+a[k]} (i<=k<=j)
实现方程的时候@环顺序非常关?l点数由到大@?/span>.否则会出现需要的值未计算的情?
记录Ҏ可以用一个数ld[i][j]记录kQ然后递归LҎq记?
1 #include<stdio.h>
2 #include<iostream>
3 using namespace std;
4 int f[35][35] = {0}, d[35][35] = {0}, ans[35] = {0}, t = 0;
5 void print(int start, int end){
6 if (start > end) return;
7 if (start == end) {ans[++t] = start; return;}
8 ans[++t] = d[start][end];
9 print(start, d[start][end]-1);
10 print(d[start][end]+1, end);
11 }
12 int main(){
13 int n, a[35] = {0}, i, j, k, l;
14 scanf("%d", &n);
15 for (i = 1; i <= n; i++){
16 scanf("%d", &a[i]);
17 f[i][i-1] = 1;
18 f[i][i] = a[i];
19 }
20 for (l = 2; l <= n; l++)
21 for (i = 1; i <= n; i++)
22 for (k = i; k <= i+l-1; k++){
23 j = i+l-1;
24 if (f[i][j] < f[i][k-1]*f[k+1][j] + a[k]){
25 f[i][j] = f[i][k-1]*f[k+1][j] + a[k];
26 d[i][j] = k;
27 }
28 }
29 printf("%d\n", f[1][n]);
30 print(1, n);
31 for (i = 1; i < t; i++) printf("%d ", ans[i]);
32 printf("%d\n", ans[t]);
33 }
34

]]> - NOIp 2006 金明的预方?/title>http://m.shnenglu.com/Climber-pI/archive/2010/10/05/128662.htmlClimber.pIClimber.pITue, 05 Oct 2010 02:11:00 GMThttp://m.shnenglu.com/Climber-pI/archive/2010/10/05/128662.htmlhttp://m.shnenglu.com/Climber-pI/comments/128662.htmlhttp://m.shnenglu.com/Climber-pI/archive/2010/10/05/128662.html#Feedback0http://m.shnenglu.com/Climber-pI/comments/commentRss/128662.htmlhttp://m.shnenglu.com/Climber-pI/services/trackbacks/128662.html题目中附件不过2个,因而主附g存在4U不同的存取情况Q可以{化ؓ分组背包问题.
[状态]f[k][v]表示d前kl物品,剩余I间为v时的最大?/span>
[方程]f[k][v] = max{f[k-1][v], f[k-1][v-c[i]]+w[i]}
注意循环序.(参见《背包九讌Ӏ?
需要注意的问题(2ơWA):
1.仔细读题Q确定编号对应的物品.
2.注意到方E中的参数非?背包c问题需注意).
1 #include<stdio.h>
2 #include<string.h>
3 #include<iostream>
4 using namespace std;
5 int c[65][4], w[65][4], f[32000], set[70] = {0};
6 int max(int a, int b){return a > b ? a : b;}
7 int main(){
8 int n, m, v, p, q, i, j, t = 0;
9 FILE *fout = fopen("budget.out", "w");
10 memset(c, -1, sizeof(c));
11 memset(w, -1, sizeof(w));
12 memset(f, 0, sizeof(f));
13 scanf("%d%d", &n, &m);
14 for (i = 0; i < m; i++){
15 scanf("%d%d%d", &v, &p, &q);
16 j = 0;
17 if (!q) {
18 c[++t][0] = v;
19 w[t][0] = v*p;
20 set[i+1] = t;
21 }
22 else{
23 q = set[q];
24 if (w[q][1] == -1){
25 //printf("dgfdgds\n");
26 c[q][1] = c[q][0] + v;
27 w[q][1] = w[q][0] + v*p;
28 }
29 else if (w[q][2] == -1){
30 c[q][2] = c[q][0] + v;
31 w[q][2] = w[q][0] + v*p;
32 c[q][3] = c[q][1] + v;
33 w[q][3] = w[q][1] + v*p;
34 }
35 }
36 }
37 for (i = 1; i <= t; i++)
38 for (v = n; v >= 0; v--)
39 for (j = 0; j < 4; j++)
40 if (c[i][j] != -1 && v-c[i][j] >= 0){
41 f[v] = max(f[v], f[v-c[i][j]]+w[i][j]);
42 }
43 printf("%d\n", f[n]);
44 }
45

]]> - Dp札记http://m.shnenglu.com/Climber-pI/archive/2010/10/03/128437.htmlClimber.pIClimber.pISun, 03 Oct 2010 04:23:00 GMThttp://m.shnenglu.com/Climber-pI/archive/2010/10/03/128437.htmlhttp://m.shnenglu.com/Climber-pI/comments/128437.htmlhttp://m.shnenglu.com/Climber-pI/archive/2010/10/03/128437.html#Feedback1http://m.shnenglu.com/Climber-pI/comments/commentRss/128437.htmlhttp://m.shnenglu.com/Climber-pI/services/trackbacks/128437.html记录写过的dp题目Qƈ分类Q尝试ȝ出某c题目的一般模?
(题目前打*的未~程验证)
【线性模型?/h3>
Tyvj 1049 最长不下降子序列问?[O(n^2) [q存在基于二分查扄O(nlogn)法]]
- [状态] f[i]表示?到i的最长不下降子序? 最大值需更新.
- [方程] if(a[j]<=a[i]) f[i] = max{f[j]} (0<j<i, 1<i<=n)
NOIp 2004 合唱队Ş [O(n^2), 双向最长上升子序列]
- [方程] f[i] = max{f[j]}+1 , 枚Dk(0<=k<=n).
Rqnoj 164 最长公共子?[记录Ҏ 子串q箋 O(n^2)]
- [状态] f[i][j]表示 子串AWi个字W??子串BWj个字W??公共子序列长?/li>
- [方程] f[i][j] = f[i-1][j-1]+1(a[i]=b[j],a[i-1]=b[j-1])|max{f[i-1][j],f[i][j-1]}
UVa 111/10405 [最长公共子序列问题,O(n^2). 可以使用滚动数组降至O(n).]
- [状态] f[i][j]表示 子串AWi个字W??子串BWj个字W??公共子序列长?/li>
- [方程] f[i][j] = f[i-1][j-1]+1(a[i]=b[j])|max{f[i-1][j],f[i][j-1]}
UVa 507 [最大连l和,O(n).]
- [状态] f[i]表示当前子序列和(非负)
- [方程] f[i]=max{f[i-1]+a[i], a[i]},递推q程中需更新最大?
【矩阉|型?/h3>
*UVa 10285 滑雪 [记忆化搜?最长下降子序列二维版本]
- [状态] f[i][j]表示?i,j)开始的最长下降子序列长度.
- [方程] f[i][j] = max{f[i-1][j], f[i][j-1], f[i+1][j], f[i][j+1]}+1(f[i][j]>f[i-1][j]..)
UVa 108
- 最大矩阵和QO(n^3)Q方E不? 最大连l和的二l版?
NOIp 2000 Ҏ取数 O(n^4)
- [状态] f[i][j][k][l]表示两h分别?i,j)?k,l)所取过的数的和.G[i][j]表示Ҏ里的?
- [方程] f[i][j][k][l] = max{f[i-1][j][k-1][l], f[i-1][j][k][l-1], f[i][j-1][k-1][l], f[i][j-1][k][l-1]}+G[i][j]+(i==k&&j==l ? 0 : G[k][l])
NOIp 2008 传纸?/p>
(1) O(n^4)
- [状态] f[x1][y1][x2][y2] 表示从出发点分别?x1,y1)?x2,y2)取的最大?G[x][y]表示该格的数.
- [方程] f[x1][y1][x2][y2] = max{f[x1-1][y1][x2-1][y2],f[x1-1][y1][x2][y2-1],f[x1][y1-1][x2-1][y2],f[x1][y1-1][x2][y2-1]}+G[x1][y1]+G[x2][y2](如果位置不重?
- [一个重要优化] 昄?strong>y2=x1+y1-x2(y2>0),因而时间复杂度可以降到O(n^3).Cena昄ȝ时从q?s降到q?.3sQ效果明?
*(2) O(n^3)
- [状态] f[p][x1][x2],p表示l过的格子数.
- [方程] f[p][x1][x2]=max{f[p-1][x1-1][x2-1],f[p-1][x1-1][x2],f[p-1][x1][x2-1],f[p-1][x1][x2]}+G[x1][p-x1]+G[x2][p-x2](如果位置不重?
USACO 5.3.4/3.3.4 [矩阵dp,O(n^2)]
- [状态] f[i][j]表示?i,j)为右下角的正方Ş最大边?/li>
- [方程] f[i][j] = min{f[i-1][j], f[i-1][j-1], f[i][j-1]}+1 (0<=i,j<n)
- [预处理] 若G[i][j]=1则f[i][j]=1.
【背包问题?/h3>
USACO 3.3.2
- [状态] f[a1][a2][a3][a4][a5]Za1件物?,a2件物?,a3件物?,a4件物?,a5件物?Ӟ所需的最h?/li>
- [方程] f[a1][a2][a3][a4][a5] = min{f[a1-p[i][1][a2-p[i][2][a3-p[i][3][a4-p[i][4]][a5-p[i][5]+p[i][0]} (0<i<=s, ak-p[i][k]>=0,p[i][0]是优惠后的h?
- [边界条g] f[0][0][0][0][0]=0;
- USACO官方解法很有启发性,用最短\Q把每种状态[a1][a2][a3][a4][a5]Qa1件物?,a2件物?,a3件物?,a4件物?,a5件物?Q看成一个点Q则臛_7776个点Q而每个优惠就是一条边Q则臛_105条边?接下来就是求[0,0,0,0,0]到目标状态的最短\Q用Dijkstra(Heap优化)卛_.
USACO 3.1.2 [完全背包问题, O(n)或O(n^2).]
- [状态] f[i][j]表示攑օWi个物体后剩余体积为j
- [方程] f[i][j] = f[i-1][j] + f[i][j-c[i]]+w[i]
USACO 3.1.6 [完全背包问题,O(n).]
- [状态] f[i]表示凑成i分邮资的最邮数.
- [方程] f[i] = min{f[i-v[j]]+1} (i-v[j] >= 0, 0<=i<n, f[0] = 0).
USACO 2.3.4
- [状态] f[i,j]表示前iU货币构成j的方法数Q用c[i]记录货币的面?
- [方程] f[i,j]=f[i-1,j]; 不用WiU货?
f[i,j]=f[i-1,j]+f[i,j-c[i]] 用第iU货币,j>=c[i]
【树形?/h3>
USACO 2.3.2
- [状态] f[i,j]表示用i个点l成深度最多ؓj的二叉树的方法数Q则Q?/li>
- [方程] f[i,j]=?f[k,j-1]×f[i-1-k,j-1])(k∈{1..i-2})
- [边界] f[1,i]=1
- 我们要求的是深度恰好为K的方法数SQ易知S=f[n,k]-f[n,k-1]。但需要注意的是,如果每次都取模,最后可能会有f[n,k]<f[n,k-1],所以可以用S=(f[n,k]-f[n,k-1]+v) mod v
【其他类型?/h3>
USACO 1.5.1 [数字三角形]
- [状态] f[i][j]表示?i,j)开始经q的数字的最大和
- [方程] f[i][j] = max{f[i+1][j], f[i+1][j+1]}+a[i][j]
USACO 3.3.5 [博弈问题]
- [状态] s[i][j]表示从i加到j的和, 枚Dl=j-i. f[i][j]表示从i到j先取者能得到的最大数字和.
- [方程] f[i][j] = s[i][j] - min{f[i+1][j], f[i][j-1]}
USACO 3.2.2
- [状态] f[n][m]表示臛_m?的n位二q制数数?/li>
- [方程] f[n][m] = f[n-1][m] + f[n-1][m-1] (f[0][m] = 1)

]]> - NOIp 2008 传纸?/title>http://m.shnenglu.com/Climber-pI/archive/2010/10/02/128362.htmlClimber.pIClimber.pISat, 02 Oct 2010 14:28:00 GMThttp://m.shnenglu.com/Climber-pI/archive/2010/10/02/128362.htmlhttp://m.shnenglu.com/Climber-pI/comments/128362.htmlhttp://m.shnenglu.com/Climber-pI/archive/2010/10/02/128362.html#Feedback0http://m.shnenglu.com/Climber-pI/comments/commentRss/128362.htmlhttp://m.shnenglu.com/Climber-pI/services/trackbacks/128362.html?000的方格取数如Z?数据加强了一点,如果是裸的四ldp可能会超?80).所以需要优?
1.普通的四维做法
【状态】f[x1][y1][x2][y2] 表示从出发点分别?x1,y1)?x2,y2)取的最大?G[x][y]表示该格的数.
【方E?strong>f[x1][y1][x2][y2] = max{f[x1-1][y1][x2-1][y2],f[x1-1][y1][x2][y2-1],f[x1][y1-1][x2-1][y2],f[x1][y1-1][x2][y2-1]}+G[x1][y1]+G[x2][y2](如果位置不重?
【一个重要优化】显然有y2=x1+y1-x2(y2>0),因而时间复杂度可以降到O(n^3).Cena昄ȝ时从q?s降到q?.3sQ效果明?
2.三维做法(参考官斚w?
【状态】f[p][x1][x2],p表示l过的格子数.
【方E?strong>f[p][x1][x2]=max{f[p-1][x1-1][x2-1],f[p-1][x1-1][x2],f[p-1][x1][x2-1],f[p-1][x1][x2]}+G[x1][p-x1]+G[x2][p-x2](如果位置不重?
未编E验?
3.更优化的做法
dy牛指出Q进一步的优化需要用?strong>最费用最大流.(NOIPl对纲,可以定不会更深?)
【Code?/p>
1 #include<stdio.h>
2 #include<iostream>
3 using namespace std;
4 int f[52][52][52][52] = {0}, n, G[52][52];
5 int max(int a, int b, int c, int d){
6 if (a < b) a= b;
7 if (a < c) a= c;
8 if (a < d) a= d;
9 return a;
10 }
11 int main(){
12 int m, n, i, j, k, l;
13 scanf("%d%d", &m, &n);
14 for (i = 1; i <= m; i++)
15 for (j = 1; j <= n; j++)
16 scanf("%d", &G[i][j]);
17 for (i = 1; i <= m; i++)
18 for (j = 1; j <= n; j++)
19 for (k = 1; k <= m; k++){
20 if (i+j-k > 0) l = i+j-k; else continue;
21 f[i][j][k][l] = max(f[i-1][j][k-1][l], f[i-1][j][k][l-1], f[i][j-1][k-1][l], f[i][j-1][k][l-1])+G[i][j]+G[k][l];
22 if (i == k && j == l) f[i][j][k][l] -= G[i][j];
23 }
24 printf("%d\n", f[m][n][m][n]);
25 }
26

]]> - NOIp 2000 Ҏ取数http://m.shnenglu.com/Climber-pI/archive/2010/10/02/128346.htmlClimber.pIClimber.pISat, 02 Oct 2010 12:14:00 GMThttp://m.shnenglu.com/Climber-pI/archive/2010/10/02/128346.htmlhttp://m.shnenglu.com/Climber-pI/comments/128346.htmlhttp://m.shnenglu.com/Climber-pI/archive/2010/10/02/128346.html#Feedback0http://m.shnenglu.com/Climber-pI/comments/commentRss/128346.htmlhttp://m.shnenglu.com/Climber-pI/services/trackbacks/128346.html单dpQ难点在于状态的表示.
题目可以看做两h同时取数Q这样就避免了后效性,可以用dp做了.
【状态】f[i][j][k][l]表示两h分别?i,j)?k,l)所取过的数的和.G[i][j]表示Ҏ里的?
【方E?strong>f[i][j][k][l] = max{f[i-1][j][k-1][l], f[i-1][j][k][l-1], f[i][j-1][k-1][l], f[i][j-1][k][l-1]}+G[i][j]+(i==k&&j==l ? 0 : G[k][l])
1ơWA.
#01: Accepted (75ms, 384KB)
#02: Accepted (0ms, 384KB)
#03: Accepted (0ms, 384KB)
#04: Accepted (28ms, 384KB)
【Code?/p>
1 #include<stdio.h>
2 #include<iostream>
3 using namespace std;
4 int f[12][12][12][12] = {0}, n, G[12][12];
5 int max(int a, int b, int c, int d){
6 if (a < b) a= b;
7 if (a < c) a= c;
8 if (a < d) a= d;
9 return a;
10 }
11 int main(){
12 int a, b, c, i, j, k, l;
13 scanf("%d", &n);
14 for(;;){
15 scanf("%d%d%d", &a, &b, &c);
16 if (a || b || c) G[a][b] = c;
17 else break;
18 }
19 for (i = 1; i <= n; i++)
20 for (j = 1; j <= n; j++)
21 for (k = 1; k <= n; k++)
22 for (l = 1; l <= n; l++){
23 f[i][j][k][l] = max(f[i-1][j][k-1][l], f[i-1][j][k][l-1], f[i][j-1][k-1][l], f[i][j-1][k][l-1])+G[i][j]+G[k][l];
24 if (i == k && j == l) f[i][j][k][l] -= G[i][j];
25 }
26 printf("%d\n", f[n][n][n][n]);
27 }
28

]]> - NOIP 2004 合唱队型http://m.shnenglu.com/Climber-pI/archive/2010/09/20/127182.htmlClimber.pIClimber.pIMon, 20 Sep 2010 13:35:00 GMThttp://m.shnenglu.com/Climber-pI/archive/2010/09/20/127182.htmlhttp://m.shnenglu.com/Climber-pI/comments/127182.htmlhttp://m.shnenglu.com/Climber-pI/archive/2010/09/20/127182.html#Feedback0http://m.shnenglu.com/Climber-pI/comments/commentRss/127182.htmlhttp://m.shnenglu.com/Climber-pI/services/trackbacks/127182.html枚Dk(0<=k<=n)Q?/strong>f[i] = max{f[j]}+1;
在tyvj提交一直RTEQ原因未?
1
#include<stdio.h>
2
#include<iostream>
3
using namespace std;
4
5
int main()
6

{
7
FILE *fin, *fout;
8
fin = fopen("chorus.in", "r");
9
fout = fopen("chorus.out", "w");
10
int i, j, k, n, T[120] =
{0}, f[120] =
{0}, ans = 0, final = 0;
11
fscanf(fin, "%d", &n);
12
for (i = 1; i <= n; i++) fscanf(fin, "%d", &T[i]);
13
for (k = 1; k <= n; k++)
14
{
15
for (i = 1; i <= n; i++) f[i] = 1;
16
for (i = 1; i <= k; i++)
17
for (j = 1; j < i; j++)
18
if (T[j] < T[i] && f[j]+1 > f[i]) f[i] = f[j]+1;
19
ans = f[k]-1;
20
for (i = 1; i <= n; i++) f[i] = 1;
21
for (i = n; i >= k; i--)
22
for (j = n; j > i; j--)
23
if (T[j] < T[i] && f[j]+1 > f[i]) f[i] = f[j]+1;
24
ans += f[k];
25
if (ans > final) final = ans;
26
}
27
fprintf(fout, "%d\n", n-final);
28
}
29

]]> - Tyvj 1049 最长不下降子序?/title>http://m.shnenglu.com/Climber-pI/archive/2010/09/11/126422.htmlClimber.pIClimber.pISat, 11 Sep 2010 13:11:00 GMThttp://m.shnenglu.com/Climber-pI/archive/2010/09/11/126422.htmlhttp://m.shnenglu.com/Climber-pI/comments/126422.htmlhttp://m.shnenglu.com/Climber-pI/archive/2010/09/11/126422.html#Feedback0http://m.shnenglu.com/Climber-pI/comments/commentRss/126422.htmlhttp://m.shnenglu.com/Climber-pI/services/trackbacks/126422.html
l典的最长不下降子序列问题,O(n^2)【还存在Z二分查找的O(nlogn)法?/span>
方程Q?strong style="FONT-FAMILY: Georgia">if(a[j]<=a[i]) f[i] = max{f[j]} (0<j<i, 1<i<=n)
可能是今天状态不好,一直在U缠l节.需要注意的是,子序列长度的最大g一定在f[n]?/span>.
1
#include<iostream>
2
using namespace std;
3
int a[5001], b[5001];
4
int max(int x, int y)
{return (x > y) ? x : y;}
5
int main()
6

{
7
int i, j, n, ans;
8
cin >> n;
9
for (i = 1; i <= n; i++)
{cin >> a[i]; b[i] = 1;}
10
for (i = 2; i <= n; i++)
11
{
12
for (j = 1; j < i; j++)
13
if (a[j] <= a[i] && b[j]+1 > b[i])
14
b[i] = b[j]+1;
15
}
16
for (i = 1; i <= n; i++)
17
if (ans < b[i]) ans = b[i];
18
cout << ans << endl;
19
}
20
马上要走了,高中q是ȝ很多Q进度让人纠l?

]]>
뾫ƷþþӰ|
2021˾Ʒþ|
þٸ۲AV|
۲ӰԺþùƷ|
þҹɫ˾Ʒ|
þùƷ|
99þþƷһ|
þˬ˸߳AV|
Ʒþþ㽶|
ƷƵþþ|
þҹۺϾþ|
þþþƷsmվ|
ƷŮþþ|
þþù99þùһ|
ձƷþþþĻ8|
һһþaþþƷۺ鶹|
þ99ƷþֻоƷ|
þþþùɫAVѹۿ|
þAëƬѹۿ|
һƷþ|
ɫۺϾþۺۺ|
ѾƷþþþþĻ|
þþþþþAv|
þþAVҰ|
þþþþþƷ|
999Ʒþþþþ|
þAVӰ|
Ʒľþþ|
91ƷùۺϾþ|
þþƷҹһ
|
þƷAVϼ|
۲ӰԺþ99|
þѾƷƵ|
99þֻоƷ|
ھƷþþþþ99|
ھƷ˾þþþ777|
ձþĻ|
þоƷ|
þþƷ|
ղƷaëƬþ|
þоƷƵ|