﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-wolf5x@bupt-随笔分类-topcoder</title><link>http://www.cppblog.com/wolf5x/category/17444.html</link><description>good luck &amp; have fun</description><language>zh-cn</language><lastBuildDate>Tue, 25 Oct 2011 14:17:07 GMT</lastBuildDate><pubDate>Tue, 25 Oct 2011 14:17:07 GMT</pubDate><ttl>60</ttl><item><title>srm 514 div1 250 600 900</title><link>http://www.cppblog.com/wolf5x/archive/2011/08/10/152947.html</link><dc:creator>&lt;A href="mailto:wolf5x1016@gmail.com"&gt;wolf5x&lt;/A&gt;</dc:creator><author>&lt;A href="mailto:wolf5x1016@gmail.com"&gt;wolf5x&lt;/A&gt;</author><pubDate>Wed, 10 Aug 2011 06:30:00 GMT</pubDate><guid>http://www.cppblog.com/wolf5x/archive/2011/08/10/152947.html</guid><wfw:comment>http://www.cppblog.com/wolf5x/comments/152947.html</wfw:comment><comments>http://www.cppblog.com/wolf5x/archive/2011/08/10/152947.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/wolf5x/comments/commentRss/152947.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wolf5x/services/trackbacks/152947.html</trackback:ping><description><![CDATA[<strong>250pt MagicalGirlLevelOneDivOne</strong><br />某神在(0,0)处, 需要走到(x,y)处(0&lt;x,y&lt;=10^9), 他只能按类似马跳的方式走, 即, 给出一个n, 他可以从(a,b)走到(a-1,b-n) (a+1,b-n) (a-1,b+n) (a+1,b+n) (a-n,b-1) (a+n,b-1) (a-n,b+1) (a+n, b+1) 中的一个.现在给出50个不同的n[1..50], 他可以以任意的n[i]方式走, 每种方式的使用次数不限. 问能否走到目的地(x,y).<br /><br />很明显, 此神可以沿任意方向2步2步的走, 即先走个(+1,-n), 再走个(+1,+n). 所以能否到终点, 只与奇偶性有关.&nbsp;<br />经过一阵分类讨论可知: <br />1) 如果x+y=0(mod 2), 则YES.&nbsp;<br />2) 如果x+y=1(mod 2), 且n[i]中有偶数, 则YES.<br />3) 否则NO.<br /><br />[杂]<br /><br /><strong>600pt MagicalGirlLevelTwoDivOne<br /></strong>给一个H*W(1&lt;=H,W&lt;=50)的矩阵A, 每一位上已经有一个1~9的数字, 或者是个'.', 在'.'处可以填上任意1~9的数字.&nbsp;再给出n和m(1&lt;=n&lt;=min{10,H}, 1&lt;=m&lt;=min{10,W}). 问一共有多少种填'?'的方法, 使得整个矩阵满足:<br />对任意的r和c, 以(r,c)开始的水平方向上连续m个数之和是奇数;<br />对任意的r和c, 以(r,c)开始的垂直方向上连续n个数之和是奇数.<br /><br />首先要注意到一个性质: 对任意r和c有 A[r,c]与A[r+n,c]的奇偶性相同. 很显然, 因为要满足A[r,c]+A[r+1,c]+...+A[r+n-1,c]与A[r+1,c]+...+A[r+n-1,c]+A[r+n,c]的奇偶性相同, 都是奇数. 列上同样有A[r,c]与A[r,c+m]奇偶性相同.<br />因此在一行上, 只用记录n位的奇偶状态, 列上同理. <strong>这样,所有的(r+pn,c+qm)都能合并成同一个点, 且只有两种状态: 奇和偶</strong>. 合并后该点为奇(或偶)的方法数, 等于组成它的所有点方法数之积. 最后整个矩阵合并压缩成一个n*m的矩阵, 就可以用状态DP来搞, 求每行每列之和都为奇的方法数. dp[n][1&lt;&lt;m], 前n行, 每一列和的奇偶性对应bit为0或1. O(1&lt;&lt;m)的转移复杂度, 转移时要注意该行状态1有奇数个.<br /><br />觉得是道很好的题, 状态设计很巧妙...<br /><br />[状态DP 状态压缩设计]<br /><br /><strong>900pt MagicalGirlLevelThreeDivOne<br /></strong>某神给出K(K&lt;=50)个01串, 每个串的长度不超过50. 用这些串组成新的串放到数组A[]里. 如果i&lt;K, 则A[i]为给出的第i个串. 否则A[i] = A[i-1] + A[i-K-1] + A[i-2*K-1] + ... + A[i-p*K-1], 其中p是使i-p*K-1&gt;=0的最大整数. 现在此神给出n, lo, hi, 要你求A[n]的子串A[n][lo...hi]中有多少个连续的1. 0&lt;=n&lt;=10^15, 0&lt;=hi&lt;= min{A[n]的长度, 10^15}, 0&lt;=lo&lt;=hi. 所有计数以0开始.<br /><br />首先随便打个表或者手推一下化简A[i]的递推式, 可以发现当i&gt;=2*K时, A[i] = A[i-1] + (A[i-K-1] + ... A[i-p*K-1]) = <strong>A[i-1] + A[i-K]</strong>, 而K&lt;=50. 所以A[i]的长度关于i是指数增长的, 50log(10^15)可能够用(严格证明不太会, 求指导#.#). <strong>因此其实n&lt;=10^15范围是坑爹的,</strong> hi不会超过A[10^4]的长度. 而这些串的前缀都是一样的, 所以A[n][lo..hi]其实与A[10^4][lo..hi]相同.<br />这样便可直接利用A[i] = A[i-1] + A[i-K]的关系分治. <strong>和用线段树求最长连续1串的思想差不多:</strong> 每个结点的状态变量是(id,lo,hi), 存放A[id][lo..hi]的最优解. 除了存放当前段的最大长度max外, 为了能合并子区间, 还要记录当前区间从左端开始连续1的个数sl, 和从右端开始连续1的个数sr. 剩下的工作与线段树无异,&nbsp;假设要求(id, lo, hi)的(max, sl, sr):<br />对于A[id], 它的左儿子就是A[id-1], 右儿子是A[id-K].<br />1)如果id&lt;2*K, 直接暴力.<br />2)如果lo&gt;=len[id-1](类似于线段树中的查询区间完全落在右儿子), 则递归查询(id-K, lo-len[id-1], hi-len[id-1]).<br />3)如果hi&lt;len[id-1], 则递归查询(id-1, lo, hi).<br />4)否则两个儿子都要查询, 并根据返回的结果求当前区间的结果.<br /><br />分治思想很强大, 用map写的"线段树"很YD, 偶依然蒻爆了.<br /><br />[分治 复杂度分析]<br /><br /><img src ="http://www.cppblog.com/wolf5x/aggbug/152947.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wolf5x/" target="_blank"><A href="mailto:wolf5x1016@gmail.com">wolf5x</A></a> 2011-08-10 14:30 <a href="http://www.cppblog.com/wolf5x/archive/2011/08/10/152947.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>srm 513 div1 500 1000</title><link>http://www.cppblog.com/wolf5x/archive/2011/07/30/152078.html</link><dc:creator>&lt;A href="mailto:wolf5x1016@gmail.com"&gt;wolf5x&lt;/A&gt;</dc:creator><author>&lt;A href="mailto:wolf5x1016@gmail.com"&gt;wolf5x&lt;/A&gt;</author><pubDate>Sat, 30 Jul 2011 03:04:00 GMT</pubDate><guid>http://www.cppblog.com/wolf5x/archive/2011/07/30/152078.html</guid><wfw:comment>http://www.cppblog.com/wolf5x/comments/152078.html</wfw:comment><comments>http://www.cppblog.com/wolf5x/archive/2011/07/30/152078.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/wolf5x/comments/commentRss/152078.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wolf5x/services/trackbacks/152078.html</trackback:ping><description><![CDATA[<strong>500pt Perfect Memory<br /></strong>题意: 某神在M*N(1&lt;=M, N&lt;=50, M*N为偶数)的格子上玩对对碰: 每个格子都有个隐藏的图形. 此神一次行动翻开2个, 如果相同, 就成功消去这2个格子. 如果不相同, 那这2个格子又恢复隐藏状态. 但是此神记忆力很NB, 能记住所有翻开过的格子是什么图形. 还有重要的一点, 他一次行动时, 是先翻开1个格子, 知道它的图形之后, 再决定怎么翻第2个格子, 而不是两个格子同时翻开. 问此神把所有格子都消去, 需要消耗的行动次数的期望.<br /><br />容易想到期望与翻格子的位置无关. 有关的量是: 当前还有多少对图形没被消去. 其中有多少对图形已经知道其中一个的位置了. so, dp[i][j], i为前者, j为后者. 一次行动中, 第1个格子肯定翻之前没翻过的(一共有2i-j个, 记为s), 除非已经知道某1对的位置, 直接把2个都翻出来消掉. 所以转移有几种情况:<br />1) 从s中翻出1个新图形. 从剩下s-1中翻出了相同图形, 消除. 这样的概率是2(i-j)/s * 1/(s-1), 转移到dp[i-1][j].<br />2) 从s中翻出1个新图形. 从剩下s-1中又翻出新图形, 这样就多了2种已知图形. 概率是2(i-j)/s * 2(i-j-1)/(s-1), 转移到dp[i][j+2].<br />3) 从s中翻出1个新图形. 从剩下s-1中翻出了之前j个已知图形中的一个. 这样, 下一次就可以消耗一次行动把那对已知图形消去, 转移到dp[i-1][j], 概率是2(i-j)/s * j/(s-1).<br />4) 从s中翻出1个已知图形. 直接翻出与它配对的消去. 转移到dp[i-1][j-1], 概率是j/s * 1.<br /><br />所以 dp[i][j] = p1*(dp[i-1][j]+1) + p2*(dp[i][j+2]+1) + p3*(dp[i-1][j]+2) + p4*(dp[i-1][j-1]+1). <br />其中2)的条件是i&gt;=j+2, 4)的条件j&gt;=1. 边界dp[i][i] = i. 最后dp[M*N][0]即为所求.<br /><br />[概率 期望 DP]<br /><br /><strong>1000pt Reflections</strong><br />题意: 某神在三维空间中玩一个游戏, 空间中有N个(N&lt;=20)平面, 每个平面都垂直于某个坐标轴, 并且与该坐标轴交于整点. 此神从(0,0,0)处出发, 想去(X,Y,Z)处. 现在他每行动一次可以做如下移动:<br />1) 走到与他相邻的1个整点上, 即(x+1, y, z) (x-1, y, z) (x, y+1, z) (x, y-1, z) (x, y, z+1) (x, y, z-1)中的一个.<br />2) 神一次行动可以利用一个平面, 移动到关于这个平面对称的点处. 每个平面在整个游戏过程中至多只能利用一次.<br />问此神到达终点花费的最少行动次数.<br /><br />易知三个方向是不相关的. 所以只用先考虑一维的情形.<br />首先要想到, 走路和反射交替, 是等效于先反射完了再一口气走到终点的. 因为在反射之前的走动, 不会被反射动作放大. 反射前移动多少步, 经过若干次反射后所到达的位置, 与不移动直接反射到达的位置, 相差正好是移动的步数.<br />所以可以转化为先反射若干次, 再行走到终点. 现在就要推出反射到达的位置公式.<br />假设每个反射轴的坐标依次是x[1], x[2], ..., x[n], 神经过第k次反射后的位置是p[k]. <br />容易推出, p[1] = 2x[1], p[2] = p[1] + 2(x[2]-x[1]) = 2x[2] - 2x[1], ... p[k] = 2x[k]-2x[k-1]+2x[k-2]-...+2*(-1)^(k-1)x[1].<br />这是很规则的正负交替求和, 正项数等于负项数, 或者比负项数多1. <br />到此问题转化得很清晰了: 在20个数中选出k个数作为正项, k(或k-1)个数作为负项, 每个数至多被选1次. 该方案的总行动次数是选出的个数(即做反射的总次数), 加上这些项之和到终点的距离(即最后一路走过去).&nbsp; <br />选数要降低复杂度, 可以把20个数分成两个集合, 每边10个数, 先各自生成2^10个和. 两边分别排序后, 从小到大枚举左边的, 记一个指针从大到小扫右边的. <br /><br />[数学 分治]<img src ="http://www.cppblog.com/wolf5x/aggbug/152078.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wolf5x/" target="_blank"><A href="mailto:wolf5x1016@gmail.com">wolf5x</A></a> 2011-07-30 11:04 <a href="http://www.cppblog.com/wolf5x/archive/2011/07/30/152078.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>srm 511 div1 500 1000</title><link>http://www.cppblog.com/wolf5x/archive/2011/07/03/150023.html</link><dc:creator>&lt;A href="mailto:wolf5x1016@gmail.com"&gt;wolf5x&lt;/A&gt;</dc:creator><author>&lt;A href="mailto:wolf5x1016@gmail.com"&gt;wolf5x&lt;/A&gt;</author><pubDate>Sat, 02 Jul 2011 19:48:00 GMT</pubDate><guid>http://www.cppblog.com/wolf5x/archive/2011/07/03/150023.html</guid><wfw:comment>http://www.cppblog.com/wolf5x/comments/150023.html</wfw:comment><comments>http://www.cppblog.com/wolf5x/archive/2011/07/03/150023.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/wolf5x/comments/commentRss/150023.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wolf5x/services/trackbacks/150023.html</trackback:ping><description><![CDATA[<strong>500pt FiveHundredEleven</strong>
		<br />给出N(N&lt;=50)个不小于0且不大于511的整数. 开始时寄存器为0, 两人轮流选取一个数, 与寄存器的值OR, 把结果覆盖写入寄存器. 数不能重复使用. 如果某人操作之后寄存器的值为511, 或者轮到某人时数都取完了, 那么这个人就算负. 问先手是否有必胜策略.<br />容易想到2^9这一维, 记录当前每一位的0/1状态. 实际上, 不需要记录当前已经选过哪些数, 而只用记录已经选了几个数, 再由当前的0/1态, 就能推算出哪些数没选过. 有些数x满足x|now != x, 这些数肯定没选过. 而对那些x|now == x的数, 不必知道它具体的值, 因为它对后续操作的影响都一样, 就是延缓一步, 把局面原封不动地丢给对方. 所以只需知道当前还有多少个这样的x没被使用过, 这个值也能由上面的信息得到. <br />这样就是一个类似极大极小的必胜必败态记忆化搜索. <br />状态为dp[1&lt;&lt;9][N], 转移为N.<br /><br />[状态DP]<br /><br /><strong>1000pt GameOfLifeDivOne</strong><br />一个长为N(N&lt;=50)的串(环状, 首尾相连, 即x[N-1]与x[0]相连), 由'0', '1' 和'?'组成, 其中'?' 处可以填上'0'或'1'. 从T=0开始, 每过1单位时间, 整个串会更新一次: 某一位, 如果上一时刻, 它, 以及与它相邻的两位, 一共有至少2个'1', 那么这一时刻它变成'1', 否则它变成'0'. 问共有多少种填'?'的方法, 使得在经过T(T&lt;=1000)时间后, 还有不少于K(K&lt;=N)个'1'. 比如'101010'-&gt;'010101'-&gt;'101010'-&gt;...; '11010'-&gt;'11101'-&gt;'11111'-&gt;...<br /><br />首先容易观察到, 两个或两个以上连续相同的位是永远不会变的. 只有01交替的子串才会发生变化. 所以任意一个串都可以看成是若干个形如 xpy的子串首尾连接而成, 而且两串的首尾要相同才能连起来, 就像[xp1y][yp2x][xp3x][xp4y].... 其中pk是01交替序列, x和y都是一位, 可能是'0'或'1'. 特别的,连续3个相同字符可以看成是xx和xx粘起来(有1位重叠). 对于一个首尾字符固定不变的01交替串, 它在T时间后有多少个'1'是很容易算的. 两头都是0的话, 如0101010-&gt;0010100-&gt;0001000, 每时间减少一个1; 两头都是1的话类似, 每时间增加一个1. 一头是0一头1, 则0和1的个数都不变, 如010101-&gt;001011-&gt;000111.&nbsp;<br />这样就有个算法的雏形, 类似背包: dp[pos][bit][one]表示: 从0到pos-1的子段, 以bit结尾, 且T时间后包含one个1的方法数. 如果从pos到某一位pos2-1, 能构造出以bit起始, 以bit2结束的交替串, 那么从状态dp[pos][bit][one]就能扩展到dp[pos2][bit2][one+one2], 则把前者加到后者上去, 其中one2是pos到pos2-1这个子串T时间后1的个数. 把原始串复制两遍, 就能比较方便地处理环.&nbsp;<br />枚举在原串中首次出现连续2个相同字符的位置startpos, 对每个startpos做一次上述DP. 把所有one&gt;=K的方法数加起来即可. 此外要先预处理出任意edg[i][b1][j][b2], 即从i到j-1能否构造出以b1开始, b2结尾的交替串, 如果能, T时间后有多少个'1'.&nbsp;<br />其实整个题就是一道背包DP, 求用若干个短棍子, 拼出一个权值&gt;=K的长棍子的方法数. 只是模型隐藏得很巧妙. orz...<br /><br />[背包DP]<br /><br /><img src ="http://www.cppblog.com/wolf5x/aggbug/150023.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wolf5x/" target="_blank"><A href="mailto:wolf5x1016@gmail.com">wolf5x</A></a> 2011-07-03 03:48 <a href="http://www.cppblog.com/wolf5x/archive/2011/07/03/150023.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>srm 507 div1 250 500 900</title><link>http://www.cppblog.com/wolf5x/archive/2011/06/01/147803.html</link><dc:creator>&lt;A href="mailto:wolf5x1016@gmail.com"&gt;wolf5x&lt;/A&gt;</dc:creator><author>&lt;A href="mailto:wolf5x1016@gmail.com"&gt;wolf5x&lt;/A&gt;</author><pubDate>Tue, 31 May 2011 16:04:00 GMT</pubDate><guid>http://www.cppblog.com/wolf5x/archive/2011/06/01/147803.html</guid><wfw:comment>http://www.cppblog.com/wolf5x/comments/147803.html</wfw:comment><comments>http://www.cppblog.com/wolf5x/archive/2011/06/01/147803.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/wolf5x/comments/commentRss/147803.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wolf5x/services/trackbacks/147803.html</trackback:ping><description><![CDATA[<strong>250p CubeStickers</strong>
		<br />给出若干个方形木板，每个木板有一种颜色。现在要选出其中6个，围出一个立方体。问是否可能使转出的立方体，任意两个相邻的面颜色不同。<br />直接按木板的总数分情况讨论就可以，但是我漏想了一种情况@.@<br />其实显然，同一种颜色最多能用两次，所以统计每种木板能用的个数之和,sigma(min(count[i],2))，和不小于6则可行。<br /><br /><strong>500p CubePacking</strong><br />给出Ns个边长为1的立方体和Nb个边长为L(2&lt;=L&lt;=10）的立方体。要找一个体积最小的长方体，使得可以把所有立方体堆进去。保证结果不超int32。<br />正是因为不超int32，所以可以直接枚举两条棱x,y，算第3条z的最小值。枚举时循环条件 x*x*x &lt;= INF, x*y*y &lt;= INF。计算z的最小值时要注意除法要向上取整，而且判断能否把边长为L的立方体都放进去的条件是(x/L)*(y/L)*(z/L) &gt;= Nb，如果z小了，要加到足够大为止。<br />[枚举]<br /><br /><strong>900p CubeBuilding</strong><br />大小相同的红、绿、蓝色的立方体，分别给R、G、B个(R,G,B&lt;=25)。把这些立方体全部搭积木一样的堆到N*N(N&lt;=25)的格子棋盘中。可以在任意格子中堆任意高的立方体。规定一种方案是合法的，如果从北向南看的侧视图中只有一种颜色。问一共有多少种堆砌的方案。<br />可以先考虑N*1的棋盘，也就是侧视图中棋盘宽度是1。先考虑没有颜色的方块怎么放，再去染色。这样不管怎么堆，<strong>看到的方块数总是等于所有格子堆的最大高度，则需要固定颜色的方块数就为这个高度，</strong>剩下的方块可以任意染色。同理N*N的棋盘，需要固定颜色的方块数等于所有列中需要固定的数量之和。要求的答案就是，先枚举固定方块的数目，把它们染某一种颜色，剩下的方块可以用组合数直接算出有多少种染色方案，乘起来，最后求和。<br />关键就是要求出每一种固定方块数目的前提下，不考虑颜色，有多少种堆放方法。<br />由前面的讨论知道，可以先在N*1的棋盘上按行扩展，需要记录的状态是当前已使用的方块数，当前的最大高度。<br />然后利用这个结果按列扩展，记录的状态是当前已使用的方块数，当前已固定的方块数。<br />ps.染色之前的方案数只用求一次，之后分别把固定的方块染成3种不同颜色，只要用组合数分别算3次，加起来就行了。<br />O(9*N^5)的算法，时限有点紧。<br />[DP]<img src ="http://www.cppblog.com/wolf5x/aggbug/147803.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wolf5x/" target="_blank"><A href="mailto:wolf5x1016@gmail.com">wolf5x</A></a> 2011-06-01 00:04 <a href="http://www.cppblog.com/wolf5x/archive/2011/06/01/147803.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>srm 506 div1 500</title><link>http://www.cppblog.com/wolf5x/archive/2011/05/12/146244.html</link><dc:creator>&lt;A href="mailto:wolf5x1016@gmail.com"&gt;wolf5x&lt;/A&gt;</dc:creator><author>&lt;A href="mailto:wolf5x1016@gmail.com"&gt;wolf5x&lt;/A&gt;</author><pubDate>Thu, 12 May 2011 03:22:00 GMT</pubDate><guid>http://www.cppblog.com/wolf5x/archive/2011/05/12/146244.html</guid><wfw:comment>http://www.cppblog.com/wolf5x/comments/146244.html</wfw:comment><comments>http://www.cppblog.com/wolf5x/archive/2011/05/12/146244.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/wolf5x/comments/commentRss/146244.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wolf5x/services/trackbacks/146244.html</trackback:ping><description><![CDATA[500pt
<br />
50个点的地图，从0开始按照顺序访问一系列点（不超过50个），访问顺序给出，一个点可能访问多次。某些点停着若干辆汽车。可以走路，也可以开车。开车的速度比走路快。但是限定一辆汽车只能使用一次，也就是下车后这辆车就作废。问按要求访问完所有点的最短总耗时。

先floyd求每对点之间走路时间和开车时间。对于访问顺序中的每一步，使用每辆车都有个节省的时间。这就相当于建个二分图，左边x是访问顺序中的每一步，右边y是每一辆车。xi与yj的边权就是第i步使用第j辆车能节省的时间。

最后结果就是总的走路时间减去最大权匹配。<br /><br />[floyd最短路 二分图最大权匹配]<img src ="http://www.cppblog.com/wolf5x/aggbug/146244.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wolf5x/" target="_blank"><A href="mailto:wolf5x1016@gmail.com">wolf5x</A></a> 2011-05-12 11:22 <a href="http://www.cppblog.com/wolf5x/archive/2011/05/12/146244.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>srm 469 div1 250 500 1000</title><link>http://www.cppblog.com/wolf5x/archive/2010/05/29/116685.html</link><dc:creator>&lt;A href="mailto:wolf5x1016@gmail.com"&gt;wolf5x&lt;/A&gt;</dc:creator><author>&lt;A href="mailto:wolf5x1016@gmail.com"&gt;wolf5x&lt;/A&gt;</author><pubDate>Sat, 29 May 2010 06:40:00 GMT</pubDate><guid>http://www.cppblog.com/wolf5x/archive/2010/05/29/116685.html</guid><wfw:comment>http://www.cppblog.com/wolf5x/comments/116685.html</wfw:comment><comments>http://www.cppblog.com/wolf5x/archive/2010/05/29/116685.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/wolf5x/comments/commentRss/116685.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wolf5x/services/trackbacks/116685.html</trackback:ping><description><![CDATA[<span style="font-weight: bold;">250p TheMoviesLevelOneDivOne</span>
		<br />电影院有n行m列的座位, 有一些已经被预订了. 求在剩下的座位中, 选出同行且相邻的两个座位的方案数.<br />可以按行列将已预订的座位排序, 然后顺便扫一遍, 算出相邻两个被预订座位之间的方案数. 最后累加.<br />也可以用个set记录不能使用的方案, 再用没有预订座位的情况下的总方案数减去之.<br /><br /><span style="font-weight: bold;">500p TheMoviesLevelTwoDivOne</span><br />若干部电影, 每部电影有一个加血的时间点. 人看电影, 每看一分钟掉一点血. 血掉到0就结束. 问怎样按排顺序使看的电影部数最多. 如果总部数相同, 取字典序最小的解输出.<br />只有20部电影, 状态DP即可.<br />为保证字典序, 可以从后往前DP, 这样每次转移时新加入的电影都是当前最先看的, 保证它先择的是最小的, 即能保证字典序最小.<br /><br />[DP]<br /><br /><span style="font-weight: bold;">1000p TheMoviesLevelThreeDivOne</span><br />若干部电影, A和B两人看每部电影的时间分别是A[i], B[i]. 初始安排, 要依次把第1,2,..,n部电影放入A或B的待看队列的队尾. A和B各自开始看自己队列中的电影, 看完一部后, 如果这是另一个人没看过的, 就加入它的队列中. 如果期间某人列队空了, 那么他就结束, 再也不看新电影了. 问有多少种初始安排方法, 能使A和B都能看完所有电影.<br />首先肯定不会出现一种安排使得A和B都卡. 因为A卡肯定发生在A看完他所有的电影之后, 且此时B没看完自己的, 所以B肯定不会卡.<br />这样就可以用总方案数2^N分别减去A卡的和B卡的方案数. 考虑A卡的情况. 假设A那一整坨东西的时长是sumA, B的第一个东西是tb1, 则A卡的条件是 sumA-tb1&lt;0. 否则B看完tb1后把ta1加在sumA后面, 这时卡的条件是(sumA+ta1)-(tb1+tb2)&lt;0. 依此, 如果在这过程中任意一次卡的条件符合, 那么后续怎么安排都是卡的. 于是用一维状态记录目前为止出现过的最小的X-Y, min, 还要一维记录当前的X-Y, cur, 以转移用. 转移时, 如果把当前电影放进A, 那么min和cur都增加A[i], 因为sumA增加了. 如果放进B, 那么用cur和B[i]来计算新的cur和min. <br />hint. cur=当前所有电影的A[i]的和-B中电影的B[i]的和, 新的min=除了新放的电影外所有放过的电影的A[i]的和-包括新电影在内的B中电影的B[i]的和.<br /><br />ps. 1000的DP都很YD啊...<br /><br />[DP]<br /><img src ="http://www.cppblog.com/wolf5x/aggbug/116685.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wolf5x/" target="_blank"><A href="mailto:wolf5x1016@gmail.com">wolf5x</A></a> 2010-05-29 14:40 <a href="http://www.cppblog.com/wolf5x/archive/2010/05/29/116685.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>srm 470 div1 250 500 1000</title><link>http://www.cppblog.com/wolf5x/archive/2010/05/28/116524.html</link><dc:creator>&lt;A href="mailto:wolf5x1016@gmail.com"&gt;wolf5x&lt;/A&gt;</dc:creator><author>&lt;A href="mailto:wolf5x1016@gmail.com"&gt;wolf5x&lt;/A&gt;</author><pubDate>Thu, 27 May 2010 16:02:00 GMT</pubDate><guid>http://www.cppblog.com/wolf5x/archive/2010/05/28/116524.html</guid><wfw:comment>http://www.cppblog.com/wolf5x/comments/116524.html</wfw:comment><comments>http://www.cppblog.com/wolf5x/archive/2010/05/28/116524.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/wolf5x/comments/commentRss/116524.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wolf5x/services/trackbacks/116524.html</trackback:ping><description><![CDATA[<span style="font-weight: bold;">250p DoorsGame</span><br />(一行并列的格子,每个格子中有某种颜色的障碍物,最多15种颜色.A在最左端,B在最右端...)<br />15种颜色,可以直接极大极小状态DP.<br />可以直接贪心,计数只有A需要拿走的颜色数,只有B需要拿走的,和两都要拿走的.<br /><br /><span style="font-weight: bold;">500p DrawingLines</span><br />(两排点,每排n个.上排的和下排的连线.事先已经有些线连好了.求考虑所有的连线方案时,连线交点个数的期望)<br />三类计数:事先已经连好的线间的交点数.新增连线和原有连线的交点数期望.新增连线之间交点期望.<br /><br /><span style="font-weight: bold;">1000p BuildingRoads</span><br />若干个点(&lt;=2500)和若干条边的无向图.每个点有点权.现在有4对特殊的点.要求选一些路径出来,使每对点连通(不同对间不要求连通),总代价是经过的所有点权之和.<br />虽然只有4对点,但是也不要一口咬定是状态DP(250p血的教训),虽然的确是状态DP...<br />最后不同点对是可以不属于同一连通分量的,所以只1次DP不容易设计状态.<br />第1次dp: dp[mask][i], mask表示连通子树中包含的特殊点, i表示这棵子树的代表节点(or根节点).<br />第2次dp: dp2[mask], mask表示已经包含的特殊点, 不要求是连通的, 但是对应的2个点要在同一分量.<br />这个过程就像,先把每个子模块做好, 再将他们拼接整合.<br /><br />ps.1000p与steiner tree有关联.<img src ="http://www.cppblog.com/wolf5x/aggbug/116524.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wolf5x/" target="_blank"><A href="mailto:wolf5x1016@gmail.com">wolf5x</A></a> 2010-05-28 00:02 <a href="http://www.cppblog.com/wolf5x/archive/2010/05/28/116524.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>topcoder code template ...</title><link>http://www.cppblog.com/wolf5x/archive/2010/04/04/111601.html</link><dc:creator>&lt;A href="mailto:wolf5x1016@gmail.com"&gt;wolf5x&lt;/A&gt;</dc:creator><author>&lt;A href="mailto:wolf5x1016@gmail.com"&gt;wolf5x&lt;/A&gt;</author><pubDate>Sun, 04 Apr 2010 10:27:00 GMT</pubDate><guid>http://www.cppblog.com/wolf5x/archive/2010/04/04/111601.html</guid><wfw:comment>http://www.cppblog.com/wolf5x/comments/111601.html</wfw:comment><comments>http://www.cppblog.com/wolf5x/archive/2010/04/04/111601.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/wolf5x/comments/commentRss/111601.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wolf5x/services/trackbacks/111601.html</trackback:ping><description><![CDATA[
		<div style="background-color: rgb(238, 238, 238); font-size: 13px; border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; width: 98%;">
				<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->
				<span style="color: rgb(0, 0, 255);">#line</span>
				<span style="color: rgb(0, 0, 0);"> $NEXTLINENUMBER$ "$FILENAME$"</span>
				<span style="color: rgb(0, 0, 0);">
						<br />#include </span>
				<span style="color: rgb(0, 0, 0);">&lt;</span>
				<span style="color: rgb(0, 0, 255);">string</span>
				<span style="color: rgb(0, 0, 0);">&gt;</span>
				<span style="color: rgb(0, 0, 0);">
						<br />#include </span>
				<span style="color: rgb(0, 0, 0);">&lt;</span>
				<span style="color: rgb(0, 0, 0);">vector</span>
				<span style="color: rgb(0, 0, 0);">&gt;</span>
				<span style="color: rgb(0, 0, 0);">
						<br />#include </span>
				<span style="color: rgb(0, 0, 0);">&lt;</span>
				<span style="color: rgb(0, 0, 0);">list</span>
				<span style="color: rgb(0, 0, 0);">&gt;</span>
				<span style="color: rgb(0, 0, 0);">
						<br />#include </span>
				<span style="color: rgb(0, 0, 0);">&lt;</span>
				<span style="color: rgb(0, 0, 0);">map</span>
				<span style="color: rgb(0, 0, 0);">&gt;</span>
				<span style="color: rgb(0, 0, 0);">
						<br />#include </span>
				<span style="color: rgb(0, 0, 0);">&lt;</span>
				<span style="color: rgb(0, 0, 0);">queue</span>
				<span style="color: rgb(0, 0, 0);">&gt;</span>
				<span style="color: rgb(0, 0, 0);">
						<br />#include </span>
				<span style="color: rgb(0, 0, 0);">&lt;</span>
				<span style="color: rgb(0, 0, 0);">stack</span>
				<span style="color: rgb(0, 0, 0);">&gt;</span>
				<span style="color: rgb(0, 0, 0);">
						<br />#include </span>
				<span style="color: rgb(0, 0, 0);">&lt;</span>
				<span style="color: rgb(0, 0, 255);">set</span>
				<span style="color: rgb(0, 0, 0);">&gt;</span>
				<span style="color: rgb(0, 0, 0);">
						<br />#include </span>
				<span style="color: rgb(0, 0, 0);">&lt;</span>
				<span style="color: rgb(0, 0, 0);">iostream</span>
				<span style="color: rgb(0, 0, 0);">&gt;</span>
				<span style="color: rgb(0, 0, 0);">
						<br />#include </span>
				<span style="color: rgb(0, 0, 0);">&lt;</span>
				<span style="color: rgb(0, 0, 0);">sstream</span>
				<span style="color: rgb(0, 0, 0);">&gt;</span>
				<span style="color: rgb(0, 0, 0);">
						<br />#include </span>
				<span style="color: rgb(0, 0, 0);">&lt;</span>
				<span style="color: rgb(0, 0, 0);">numeric</span>
				<span style="color: rgb(0, 0, 0);">&gt;</span>
				<span style="color: rgb(0, 0, 0);">
						<br />#include </span>
				<span style="color: rgb(0, 0, 0);">&lt;</span>
				<span style="color: rgb(0, 0, 0);">algorithm</span>
				<span style="color: rgb(0, 0, 0);">&gt;</span>
				<span style="color: rgb(0, 0, 0);">
						<br />#include </span>
				<span style="color: rgb(0, 0, 0);">&lt;</span>
				<span style="color: rgb(0, 0, 0);">cmath</span>
				<span style="color: rgb(0, 0, 0);">&gt;</span>
				<span style="color: rgb(0, 0, 0);">
						<br />#include </span>
				<span style="color: rgb(0, 0, 0);">&lt;</span>
				<span style="color: rgb(0, 0, 0);">cctype</span>
				<span style="color: rgb(0, 0, 0);">&gt;</span>
				<span style="color: rgb(0, 0, 0);">
						<br />#include </span>
				<span style="color: rgb(0, 0, 0);">&lt;</span>
				<span style="color: rgb(0, 0, 0);">cstdlib</span>
				<span style="color: rgb(0, 0, 0);">&gt;</span>
				<span style="color: rgb(0, 0, 0);">
						<br />#include </span>
				<span style="color: rgb(0, 0, 0);">&lt;</span>
				<span style="color: rgb(0, 0, 0);">cstdio</span>
				<span style="color: rgb(0, 0, 0);">&gt;</span>
				<span style="color: rgb(0, 0, 0);">
						<br />#include </span>
				<span style="color: rgb(0, 0, 0);">&lt;</span>
				<span style="color: rgb(0, 0, 0);">cstring</span>
				<span style="color: rgb(0, 0, 0);">&gt;</span>
				<span style="color: rgb(0, 0, 0);">
						<br />
				</span>
				<span style="color: rgb(0, 0, 255);">using</span>
				<span style="color: rgb(0, 0, 0);"> </span>
				<span style="color: rgb(0, 0, 255);">namespace</span>
				<span style="color: rgb(0, 0, 0);"> std;<br /><br /></span>
				<span style="color: rgb(0, 0, 255);">#define</span>
				<span style="color: rgb(0, 0, 0);"> CLR(x) memset((x),0,sizeof(x))</span>
				<span style="color: rgb(0, 0, 0);">
						<br />
				</span>
				<span style="color: rgb(0, 0, 255);">#define</span>
				<span style="color: rgb(0, 0, 0);"> SET(x,y) memset((x),(y),sizeof(x))</span>
				<span style="color: rgb(0, 0, 0);">
						<br />
				</span>
				<span style="color: rgb(0, 0, 255);">#define</span>
				<span style="color: rgb(0, 0, 0);"> REP(i,x) for(int i=0;i&lt;(x);i++)</span>
				<span style="color: rgb(0, 0, 0);">
						<br />
				</span>
				<span style="color: rgb(0, 0, 255);">#define</span>
				<span style="color: rgb(0, 0, 0);"> FOR(i,x,y) for(int i=(x);i&lt;(y);i++)</span>
				<span style="color: rgb(0, 0, 0);">
						<br />
				</span>
				<span style="color: rgb(0, 0, 255);">#define</span>
				<span style="color: rgb(0, 0, 0);"> VI vector&lt;int&gt; </span>
				<span style="color: rgb(0, 0, 0);">
						<br />
				</span>
				<span style="color: rgb(0, 0, 255);">#define</span>
				<span style="color: rgb(0, 0, 0);"> PB(i,x) (i).push_back(x)</span>
				<span style="color: rgb(0, 0, 0);">
						<br />
				</span>
				<span style="color: rgb(0, 0, 255);">#define</span>
				<span style="color: rgb(0, 0, 0);"> MP(x,y) make_pair((x),(y))</span>
				<span style="color: rgb(0, 0, 0);">
						<br />
						<br />
				</span>
				<span style="color: rgb(0, 0, 255);">class</span>
				<span style="color: rgb(0, 0, 0);"> $CLASSNAME$ {<br /></span>
				<span style="color: rgb(0, 0, 255);">public</span>
				<span style="color: rgb(0, 0, 0);">:<br />    $RC$ $METHODNAME$($METHODPARMS$) <br />    {<br />        </span>
				<span style="color: rgb(0, 128, 0);">//</span>
				<span style="color: rgb(0, 128, 0);">have some fun here</span>
				<span style="color: rgb(0, 128, 0);">
						<br />
				</span>
				<span style="color: rgb(0, 0, 0);">    }<br />    $TESTCODE$<br />};<br /><br /></span>
				<span style="color: rgb(0, 128, 0);">//</span>
				<span style="color: rgb(0, 128, 0);"> BEGIN CUT HERE </span>
				<span style="color: rgb(0, 128, 0);">
						<br />
				</span>
				<span style="color: rgb(0, 0, 255);">int</span>
				<span style="color: rgb(0, 0, 0);"> main()<br />{<br />    $CLASSNAME$ ___test; <br />    ___test.run_test(</span>
				<span style="color: rgb(0, 0, 0);">-</span>
				<span style="color: rgb(0, 0, 0);">1</span>
				<span style="color: rgb(0, 0, 0);">); <br />    system(</span>
				<span style="color: rgb(0, 0, 0);">"</span>
				<span style="color: rgb(0, 0, 0);">pause</span>
				<span style="color: rgb(0, 0, 0);">"</span>
				<span style="color: rgb(0, 0, 0);">);<br />} <br /> </span>
				<span style="color: rgb(0, 128, 0);">//</span>
				<span style="color: rgb(0, 128, 0);"> END CUT HERE </span>
		</div>
		<br />
<img src ="http://www.cppblog.com/wolf5x/aggbug/111601.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wolf5x/" target="_blank"><A href="mailto:wolf5x1016@gmail.com">wolf5x</A></a> 2010-04-04 18:27 <a href="http://www.cppblog.com/wolf5x/archive/2010/04/04/111601.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>