ManuShi98

真彩希帆のファン


  • Home

  • About

  • Tags

  • Categories

  • Archives

  • Search

BZOJ - 1001 狼抓兔子(网络流最小割转对偶图最短路)

Posted on 2018-05-16 | In 算法 , 网络流

思路

题意可得我们要求一个网络流的最小割。但由于dinic时间复杂度是O(EV^2),显然对于这张图来说边数会达到10^6以上,所以dinic的时间复杂度是不满足我们的要求的。所以我们学习一个O(nlogn)的姿势——网络流最小割转对偶图最短路。对偶图的概念摸这里。通过观察我们能发现对偶图中的环即对应着原图的割,但直接用对偶图环的性质我们并没有什么高效的算法。所以我们在建图过程中稍作修改,我们这样对样例建图:
bzoj1001
我们先在左上角的源点和右下角的汇点连一条线,如上图,然后再建对偶图。这时比较对偶图的性质显然可以知道对偶图中0到1的最短路即为最小割,运用spfa或dijkstra堆优化就能做到O(nlogn)。

Read more »

CodeForces Gym - 100959J Ropes(prufer序列)

Posted on 2018-04-13 | In 算法 , prufer序列

prufer序列学习笔记

Read more »

POJ - 2114 Boatherds(点分治)

Posted on 2018-04-10 | In 算法 , 点分治

思路

点分治裸题,但统计长度为k的路径时需要注意要使用O(n)的算法(我用了O(n^2)的居然没发现,TLE。。)具体思路就是先对depth排序,然后当depth[l]+depth[r]==k是,因为可能有与depth[l],depth[r]深度相同的,所以统计相同的个数直接numl*numr计算。若depth[l]+depth[r]<k那么l++,因为这时对当前的l能满足条件的r都已经计算过了,所以直接l++。若depth[l]+depth[r]>k,思路一样,r—。

Read more »

HDU - 4089 Activation(概率dp)

Posted on 2018-04-05 | In 算法 , 动态规划 , 概率dp

思路

本题我们定义dp[i][j]为队伍中有i个人Tomato排在第j个时,服务器崩溃且排在他前面的人有大于等于k个人的概率。
一共有三个转移方程(注意是逆推):

  1. dp[i][1]=p1*dp[i][1]+p2*dp[i][i]+p4,因为要求无后效性,化简可得dp[i][1]=p2/(1-p1)*dp[i][i]+p4/(1-p1)
  2. 对j属于[1,k]有:dp[i][j]=p1*dp[i][j]+p2*dp[i][j-1]+p3*dp[i-1][j-1]+p4,同样因为要求无后效性,化简可得dp[i][j]=p2/(1-p1)*dp[i][j-1]+p3/(1-p1)*dp[i-1][j-1]+p4/(1-p1)
  3. 对j属于[k+1,n]有:dp[i][j]=p1*dp[i][j]+p2*dp[i][j-1]+p3*dp[i-1][j-1],化简可得dp[i][j]=p2/(1-p1)*dp[i][j-1]+p3/(1-p1)*dp[i-1][j-1]

接下来我们发现这个dp转移方程。。构成了一个环?不过这道题并没有用到高斯消元,我们将dp转移中第j项与dp[i]即当前状态无关的令为一个常数c[j],然后对第一个方程迭代。我们最后化简可得如下式子:
hdu4089
然后我们用转移方程求出所有dp[i]的状态,然后dp[n][m]就是答案。这题有个比较奇怪的点,似乎如果不对p4约等于0的情况进行特判会出问题?不是很懂为什么。。

Read more »

CodeForces - 864E Fire(dp)

Posted on 2018-04-03 | In 算法 , 动态规划 , 线性dp

思路

01背包dp,需要注意的是物品过了d[i]秒后就会焚毁,这使得背包的选取顺序影响了dp的更新。这是为什么呢?考虑我们背包的过程,我们为了避免选取顺序的影响强制给了背包一个顺序,而由于我们先放了a大小的,后面b大小只要空间足够的肯定能放,反之亦然。也就是说背包的选取顺序对dp的更新没有影响。但是这里因为物品焚毁,如果我们先放了a大小的结果发现b已经焚毁了就没法更新状态了,但实际上我们能把先焚毁的b放进去来更新状态,所以我们将d排序后再跑背包dp,这样保证了先焚毁的能更新后焚毁的物品的状态。

Read more »

CodeForces - 56D Changing a String(dp)

Posted on 2018-04-01 | In 算法 , 动态规划 , 线性dp

思路

第一反应是最长公共子序列乱搞。。显然不对啊
我们令dp[i][j]为从s1(1,i)转换到s2(1,j)所需要的最少步数。分四种情况讨论:

  1. 插入:dp[i][j]=min(dp[i][j],dp[i][j-1]+1),我们已经知道从s1(1,i)转换到s2(1,j-1),所以在j-1尾插入字来尝试更新dp[i][j]
  2. 删除:dp[i][j]=min(dp[i][j],dp[i-1][j]+1),我们已经知道从s1(1,i-1)转换到s2(1,j),因为已经转换完成,所以i比之前i-1的状态只需要删去一个字符就能变成s2(1,j)
  3. 替换:dp[i][j]=dp[i-1][j-1]+1,转移显而易见
  4. 不变:dp[i][j]=dp[i-1][j-1],同样是转移显而易见。

最后打印路径即可,因为这里操作可逆

Read more »

CodeForces Gym - 101615D Rainbow Roads(树上差分)

Posted on 2018-03-28 | In 算法 , 树上差分

思路

对于一个点,考虑可能出现同色边的情况,可以分为两种
(1)两个儿子是相同颜色的
CodeForcesGym-101615D-1
如上图,显然2-4,2-5边是相同颜色的,同时对于4,5节点的子树上的点都不是good的,因为显然会有一条从5(4)到该点的一条不是rainbow road的路径。所以我们需要对这样的子树进行染色。
(2)父亲和儿子是相同颜色的
CodeForcesGym-101615D-2
这种情况下我们需要将除2和2的子树以外的所有节点进行染色。因为他们总有一条过1-2-5非彩虹路,所以那些节点不是good的。
现在我们解决了如何找出非good点这个问题,但是统计依然是大问题。我们需要对子树进行染色。我们注意到我们只需要最后输出一次答案即可而不需要一直回答询问,所以我们可以考虑树上差分。我们首先求出一个dfs序,得到st[i]和ed[i],对于第一种情况,因为st[i]和ed[i]之间的节点就是i和i的子树,我们使用差分即可。对于第二种情况,我们在根上+1,然后在子树上抵消这个+1即可。

Read more »

BZOJ - 2301 Problem b(莫比乌斯反演+容斥)

Posted on 2018-03-21 | In 算法 , 莫比乌斯反演

思路

莫比乌斯反演入门题,看popoqqq的ppt看了好久(本篇博客也是参考了很多他的ppt,然后加上了一些自己的理解),深深感到OI大佬的厉害Orz。

Read more »

HDU - 3853 LOOPS(概率dp)

Posted on 2018-03-16 | In 算法 , 动态规划 , 概率dp

思路

概率/期望dp。本题我们能通过全期望公式得到dp[i][j]=dp[i+1][j]*map[i][j][2]+dp[i][j+1]*map[i][j][1]+dp[i][j]*map[i][j][0]+2得到(2是消耗的能量)。由于dp要求无后效性,我们移项得到dp[i][j]=(dp[i+1][j]*map[i][j][2]+dp[i][j+1]*map[i][j][1]+2)/(1-map[i][j][0])。需要注意的是对于概率dp,我们通常正推,但期望dp我们通常反着推。就期望dp来说,正推最大的困难点在于一个点可能是直接转移过来的,但也有可能在原地停留后再转移,即转移概率需要另外计算,所以概率并不是简单的map[i][j][k]。对于本题来说正推计算后的公式实际上还能接受,但对像hdu4405这种题来说正推的转移太复杂了,所以我们考虑泛用性更好的反推。对于一个点X,显然有如下转移
hdu-3853-1
那我们显然地,通过这个转移从起点到终点的期望等于使用这个转移从终点到起点的期望。对于这个反推我们考虑从右下往左上推,注意,这个时候每个点的期望是从右边的点,下面的点和自己推来的,这意味着原来正推的时候该点左下角的点对该点下面的点的影响是没有的,所以可以放心的使用全期望公式。
总结一下,我们使用反推通常是因为我们可以很方便地知道一个点到下一个点的转移概率,这个概率在反推的时候是不用额外计算的。但正推就要考虑之前的点有没有通过多种方式转移到这个点,我们需要考虑转移的概率究竟是几。两相比较之下显然反推比较优秀。

Read more »

CodeForces - 739B Alyona and a tree(树上差分+二分)

Posted on 2018-03-16 | In 算法 , 树上差分

思路

很显然对于任意一个点u,如果有一个点v满足dist(v,u)<=a[u],那么v到u路径上的所有点都是满足条件的点。所以我们考虑二分(也可以倍增),找到第一个符合条件的点。然后我们使用树上差分来统计结果。我们令所有点ans=1,再对符合条件的点的父亲我们ans—,最后dfs的时候从子节点往父节点合并答案即可。注意最后答案要ans-1,因为初始ans=1即自己被多统计了一次。

Read more »
1…456…10

93 posts
70 categories
61 tags
GitHub E-Mail
Links
  • numberer
© 2023 ManuShi98
Powered by Hexo
|
Theme — NexT.Pisces v5.1.4