02 2016 档案
摘要:简单矩阵快速幂。 if(m==1) MOD=10; if(m==2) MOD=100; if(m==3) MOD=1000; if(m==4) MOD=10000; 剩下的就是矩阵快速幂求斐波那契数列第n项取模 #include<cstdio> #include<cstring> #include<
阅读全文
摘要:矩阵快速幂。 首先得到公式 然后构造矩阵,用矩阵加速 取模函数需要自己写一下,是数论中的取模。 #include<cstdio> #include<cstring> #include<cmath> #include<vector> #include<algorithm> using namespac
阅读全文
摘要:区间DP。 这题好难想....做区间DP专题的时候,第一题看的就是这题,发现不会然后一直没去做,直到今天专题中其余的题都切完了再看这题...依旧无头绪,还是看了题解....看了也发现好难。。。 #include<cstdio> #include<cstring> #include<cmath> #i
阅读全文
摘要:区间DP。 区间DP专题做到现在,发现这题思路最难......自己想出来方法正确性应该没问题,但时间复杂度高达26000000..都不敢写了。 最终看了题解,发现真的不在我目前能力范围之内......编码量很少,但思维成分高。。。 首先:dp[i][j]表示把[i,j]空白串刷成t串[i,j]所需的
阅读全文
摘要:区间DP。dp[i][j][h][k]表示[i,j]这段区间染色,左端点为颜色h,右端点为颜色k的方案数。 递推式很容易写出来。注意中间过程爆int。 #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #in
阅读全文
摘要:区间DP。 首先求凸包判断是否为凸多边形。 如果是凸多边形:假设现在要切割连续的一段点,最外面两个一定是要切一刀的,内部怎么切达到最优解就是求子区间最优解,因此可以区间DP。 #include<cstdio> #include<cmath> #include<cstring> #include<al
阅读全文
摘要:区间DP。 首先很容易想到送货顺序是起点不断向两边扩展的。这样可以用区间DP做。 但是,如果我们这样设计dp,dp[i][j][X]表示[i,j]这一段区间都送完,最终在左端点、右端点的最小花费,是有后效性的。 为什么有后效性? 如果有一种方案得到的dp[5][8][0]较小,但走的总路程较多,另一
阅读全文
摘要:区间DP。 我们先给人编号,从左到右编号1到n。 对于整段区间,必然有一个人是最后上场的,假设是编号为S的最后上场, 因为是栈维护的顺序,那么编号1至S-1这S-1个人,必然是第1--S-1个上场的(具体顺序不知), 而编号S+1至n这些人必然是第S--n-1个上场的(具体顺序不知)。 假设我们知道
阅读全文
摘要:神题。同学指教。1秒AC。。。http://blog.csdn.net/jtjy568805874/article/details/50724656 #include<cstdio> #include<cstring> #include<ctime> #include<algorithm> usin
阅读全文
摘要:很简单的博弈题.....算几组能得到规律了。 某个状态先手要赢 等价于 之前有一种状态是后手赢,先手可以保证让现在这个状态到达那个状态 #include<cstdio> #include<cstring> #include<ctime> #include<algorithm> using names
阅读全文
摘要:状态压缩。 每一个人所需的物品对应一个数字,统计一个每个数字有几个。每一种提供物品的状态也对应一个数字,然后暴力判断。 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn
阅读全文
摘要:最长上升序列变形。LIS线段树写法。 #include<cstdio> #include<cstring> #include<cmath> #include<string> #include<vector> #include<queue> #include<algorithm> #include<i
阅读全文
摘要:DP。 具体做法:dp[i][j]表示长度为 i 的括号串,前缀和(左括号表示1,右括号表示-1)为 j 的有几种。 状态转移很容易得到:dp[i][j]=dp[i - 1][j + 1]+dp[i - 1][j - 1],表示 i 这位分别放上右括号和左括号。 然后就是要处理题目的问题了: 我们可
阅读全文
摘要:2014浙江省赛题。 简单递推。f[i]表示加入第 i 个数字之后答案的新增加量。即以 i 位置作为区间的结尾对答案作出的贡献。 那么很容易得到,f[i]=f[i-1]+a[i]*(i-pre[a[i]]),pre[a[i]]表示a[i]上一次出现的位置。 然后把f[1]到f[n]加起来就是答案了。
阅读全文
摘要:2015浙江省赛B题。我用了枚举+二分。。时间复杂度o(64*n),1900ms跑过的。应该有更好的方法。 #include<cstdio> #include<cstring> #include<cmath> #include<string> #include<vector> #include<qu
阅读全文
摘要:如果原图不连通,直接输出0. 如果原图连通,删除X条边之后要保证新图连通,再看数据是n+1条边-->因此,最多只能删去两条边。 因为n=100,可以枚举进行验证,枚举删去每一条边是否连通,枚举删去每两条边是否连通,验证是否连通可以用并查集,可以BFS。 #include<cstdio> #inclu
阅读全文
摘要:先把偶数行换了,再把偶数列换了,这样能得到相同的颜色,次数为n/2+m/2次,但是为什么为最小值,不会证明,直觉。 #include<cstdio> #include<cstring> #include<cmath> #include<string> #include<vector> #includ
阅读全文
摘要:计算前两盘A赢,最后一盘B赢的情况下,B获得的球的值总和大于A获得的球总和值的概率。 存储每一对球的差值有几个,然后处理一下前缀和,暴力枚举就好了...... #include<cstdio> #include<cstring> #include<cmath> #include<string> #i
阅读全文
摘要:构造AC的。左右两边都先不用6的倍数,然后哪边数字大那一边往回退一下,然后再比较哪边数字大.......直到结束 #include<cstdio> #include<cstring> #include<cmath> #include<string> #include<vector> #include
阅读全文
摘要:瞎搞题。。。凭直觉+猜测写了一发,居然AC了。。 #include<cstdio> #include<cstring> #include<cmath> #include<string> #include<vector> #include<queue> #include<algorithm> #inc
阅读全文
摘要:枚举一下就好,时间复杂度o(n*n) #include<cstdio> #include<cstring> #include<cmath> #include<string> #include<vector> #include<queue> #include<algorithm> #include<i
阅读全文
摘要:拓扑排序。2014浙江省赛题。 先看行: 如果这行没有黑色,那么这个行操作肯定不操作。 如果这行全是黑色,那么看每一列,如果列上有白色,那么这一列连一条边到这一行,代表这一列画完才画那一行 如果不全是黑色,那么看这一行的每一个元素,如果有白色的,那么白色所在列向这一行连边。 再看列: 与看行类似,不
阅读全文
摘要:手上有好多卡牌:卡牌分两种,A类和B类A类卡:仅有一个攻击力G[i],和一个血量HP[i]B类卡:有一个攻击力G[i],和一个血量HP[i],还有一个属性:每受到1点伤害,攻击力增加K[i] 现在轮到我攻击对方。每张卡可以攻击一次,可以攻击自己的卡牌也可以直接攻击对方。当卡牌的HP小于等于0的时候,
阅读全文
摘要:状压DP。我认为是数据水了,用打死了哪几只作为状态,AC代码只需要保存当前状态的最大血量,完全没有考虑攻击力大小。 个人认为正确DP应该这样的:dp[状态][等级],但这样写不能AC,时间复杂度会很大,但答案应该是正确的。 #include<cstdio> #include<cstring> #in
阅读全文
摘要:状压DP。 首先很容易想到:一个点要被固定的话,必须有两个已经固定了的点与这个点连边。 再看N的范围,秒想到状压DP,秒出思路。1表示这个点已经被固定,0表示还没被固定。 推导某个状态的时候,枚举一下这个状态下所有被固定的点哪个是最后被固定的,即可得出这个状态的最优解。 #include<cstdi
阅读全文
摘要:构造。应该有多种构造方法。做的时候WA了好几发,怀疑做法是错的,事实上是代码写搓了。。 我是这样构造的:先从上往下左右放奇数,再从下往上左右填偶数 (一)如果n/2是偶数(以12为例) 左边列是内环,右边列是外环 (二)如果n/2是奇数(以10为例) 左边列是内环,右边列是外环 #include <
阅读全文
摘要:(莫名其妙的被一个叫布布扣的网站收录了......什么鬼) 简单DP。dp[i][j]表示把前i个数字分成j段的最优解, 递推式很容易写: (其中sum[]是前缀和;p <= i - L,并且前p个数能分成j-1段,下文不再说明p的范围,都是一样的) 得到递推式之后暴力DP的话复杂度为o(n*n*k
阅读全文
摘要:背包。注释写详细了。 本想这样写:每个组内各自做背包,然后组间做背包,但是由于这题M=10000,时间复杂度太大。 #include<cstdio> #include<cstring> #include<cmath> #include<queue> #include<vector> #include
阅读全文
摘要:二分答案+状压DFS+BFS预处理 答案是通过二分得到的,每次得到的mid进行验证,验证可以状压DP也可以DFS DFS||DP的时候,如果一格一格走,会TLE。事实上我们只关心Y、G、F这几个格子的状态,对于S不知道情况对得到答案毫无影响,所以采用BFS预处理,求出Y、G、F这几个格子两两之间的最
阅读全文
摘要:是一个简单构造题。 请观察公式: 绝对值里面的就是 |di-(n-i)|,即di与(n-i)的差值的绝对值。 事实上,对于任何n,我们都可以构造出来每一个i的di与(n-i)的差值为0。 换句话说,就是这个最小值一定可以构造出来是0。 假设输入是6:那么可以这样构造:1 3 5 5 3 1 2 4
阅读全文
摘要:简单题,公式打了个表,查询的时候二分一下就行。也可以直接o(1)公式出解。 #include <stdio.h> #include <algorithm> #include <string.h> #include <queue> #include <stack> #include <map> #in
阅读全文
摘要:水题。 #include <stdio.h> #include <algorithm> #include <string.h> #include <queue> #include <stack> #include <map> #include <vector> using namespace std
阅读全文
摘要:预处理p[i],p[i]表示:【p[i],i】这段闭区间上所有数字都是a[i] 询问的时候,如果xi==a[ri]并且p[ri]<=li,一定无解 剩下的情况都是有解的,如果xi!=a[ri],那么输出ri,否则输出p[ri]-1。 另外,看到有大牛博客说可以用线段树,大致是这样的: 线段树保存区间
阅读全文
摘要:这题目测是数据水了。我这种暴力写法显然是可以卡超时的。 假设有2000个点,15000条边,前面10000条不能构成树,后面5000条可以,这种数据显然可以卡超时。 #include <stdio.h> #include <algorithm> #include <string.h> #includ
阅读全文
摘要:N个点中任意选取四个点,就能产生一个圆内的交点,所以圆内总共有C(N,4)个交点,圆上有N个,相加就可以了。 注意:组合数运算的时候会爆longlong,中间先除一下就可以了。 #include <stdio.h> #include <algorithm> #include <string.h> #
阅读全文
摘要:想了一下发现是斐波那契数列.....水题 #include <stdio.h> #include <algorithm> #include <string.h> #include <queue> #include <stack> #include <map> #include <vector> us
阅读全文
摘要:暴力匹配+一点判断 #include <stdio.h> #include <algorithm> #include <string.h> #include <queue> #include <stack> #include <map> #include <vector> using namespa
阅读全文
摘要:简单构造 #include <stdio.h> #include <algorithm> #include <string.h> #include <queue> #include <stack> #include <map> #include <vector> using namespace st
阅读全文
摘要:贪心水题 #include <stdio.h> #include <algorithm> #include <string.h> #include <queue> #include <stack> #include <map> #include <vector> using namespace st
阅读全文
摘要:神奇的构造题,我的思路比较奇葩。搞了好久,看到WA on 91我绝望了,然后自己造数据,找到了错误,总算是AC了,现在是凌晨0:24分,看到AC之后,感动China! 我写的代码无比的长。。。。。应该有很简单的方法吧。。。。。没想到。 #include <stdio.h> #include <alg
阅读全文
摘要:组合数学题。好难啊,请教了Xiang578大神&&看了他题解才会的...... 甩上题解链接:http://blog.csdn.net/xinag578/article/details/50645160 另外还发现了组合数递推公式实际上就是一个01背包。 #include <stdio.h> #in
阅读全文
摘要:树形DP+LCA+思路。这题可真是有点难度......所以准备详细写一下题解。 题意:给一颗无根树,有Q次询问,每次询问指定一个根节点X,然后让你计算Y节点的儿子和子孙中,编号最小的节点是多少。 我们先以1为根节点进行一次树形DP,记录下每个节点的儿子和子孙中,编号最小的节点是多少。 首先很容易想到
阅读全文
摘要:树形DP,和背包差不多。dp[now][x]表示now这个节点的子树上,花费为x的时候,获得的最大防御能力(保证敌方HP<=0) #include<cstdio> #include<cstring> #include<queue> #include<algorithm> using namespac
阅读全文
摘要:树形背包。DP递推的思路很简单.... 但是由于节点有15万个,先不论空间复杂度,这样开dp数组 dp[150000+10][300+10],如果初始化是memset(dp,-1,sizeof dp),则必然超时。 所以需要一个状态数剪枝。。。即记录这个节点最多组合的数量。 UVALive是不限制内
阅读全文
摘要:可以树形DP,也可以用网络流(最大流=最小割) 用树形DP的话,这题就是 HDU 3586 简化版,HDU 3586还需要二分查找。 #include<cstdio> #include<cstring> #include<cmath> #include<ctime> #include<map> #i
阅读全文
摘要:二分+树形DP验证。 答案是通过二分查找得到的,对于每一次二分到的值,进行验证,是否可行。 可以用树形DP来求解所有叶子节点不能向根节点传送消息的最小费用,dp[i] 表示 节点i 的子树的叶子结点都不能向i传送消息的最小费用,这样很容易递推。 #include<cstdio> #include<c
阅读全文
摘要:树形DP水题。判断取法是否唯一,dp的时候记录一下每个状态从下面的子节点推导过来的时候是否唯一即可。 #include<cstdio> #include<cstring> #include<cmath> #include<ctime> #include<map> #include<vector> #
阅读全文
摘要:树形DP。这题折腾了一天,很开心,总算是独立AC了。题意读了好几遍,发现并不是很明确。 注意这个坑:即使该洞bug数为0,要获得该洞brain值,也需要至少一人经过该洞穴,但这个人可以不停留在这个点 估计这题代码我写的最长了。。。。有好多地方可以简化。。。 留几组数据: 第一组:答案是200 2 1
阅读全文
摘要:树形DP。 dp[i][1]表示 在编号为 i 的节点上放置一个人,覆盖 编号为 i 的节点 的子树上所有边 需要的数量。 dp[i][0]表示 在编号为 i 的节点上不放置人,覆盖 编号为 i 的节点 的子树上所有边 需要的数量。 也可以用二分图匹配来做,在数量上,二分图的最小点覆盖数=二分图的最
阅读全文
摘要:树形DP。树上背包AC了......每一个节点做一次背包。dp[id][X] 表示 编号为id的节点的子树上 选取X个节点 获得的最大价值 #include<cstdio> #include<cstring> #include<cmath> #include<ctime> #include<vect
阅读全文
摘要:树形DP入门题。感觉负数的那些节点一定是不要选的,本着这个原则写了一发...AC了。 #include<cstdio> #include<cstring> #include<cmath> #include<ctime> #include<vector> #include<algorithm> usi
阅读全文
摘要:暴力。每次合并两个点之后,把新产生的连通关系都记录下来。 #include<cstdio> #include<algorithm> #include<vector> #include<cstring> using namespace std; int T, n, m, p, u, v, G; int
阅读全文
摘要:方法可以转化一下,先计算每一个鲨鱼在自己范围内的数能被所给素数整除的个数有几个,从而得到能被整除的概率,设为f1,不能被整除的概率设为f2. 然后计算每相邻两只鲨鱼能获得钱的期望概率,f=w[id1].f1*w[id2].f2+w[id1].f2*w[id2].f1+w[id1].f1*w[id2]
阅读全文
摘要:记录一下每个对角线上有几个,然后就可以算了 #include<cstdio> #include<cstring> #include<cmath> #include<ctime> #include<vector> #include<algorithm> using namespace std; con
阅读全文
摘要:水题 #include<cstdio> #include<cstring> #include<cmath> #include<ctime> #include<vector> #include<algorithm> using namespace std; int n; long long a[100
阅读全文
摘要:暴力枚举+idea。做的时候mod写错了,写成了1000000009,找了两个多小时才发现...... a[1],a[2],a[3]....a[N] b[1],b[2],b[3]....b[N] 首先需要枚举b[1]...b[N]与a[1]进行组合。 然后对a[2]...a[N]从小到大排序 对b[
阅读全文
摘要:模拟题,代码写得比较乱。。。 #include<cstdio> #include<cstring> #include<cmath> #include<queue> #include<vector> #include<algorithm> using namespace std; char s[500
阅读全文
摘要:简单DP。dp[i][j]表示走到这格的最大金钱数。 #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; const int maxn=1000+10; int n,m
阅读全文
摘要:预处理打表,sum[i][j]表示1.。。。。i这些数字中 j 有几个。然后就很好处理询问了。 #include<stdio.h> #include<math.h> #include<string.h> int sum[100000+10][15]; char s[100000+10]; int n
阅读全文
摘要:有些问题,不做实践与猜测,可能一辈子也想不出答案,例如这题。 #include<stdio.h> #include<math.h> long long x; int main() { while(~scanf("%lld",&x)){ if(x<7) printf("-1\n"); else pri
阅读全文
摘要:背包。dp[i]=1表示i这种差值能被组合出来,差值有负数,所以用sum表示0,0表示-sum,2*sum表示sum。 询问X的时候,只需看dp[sum+X]或者dp[sum-X]是否有一个为1,注意RE。 #include<cstdio> #include<cstring> #include<cm
阅读全文
摘要:第一反应是在凸包上随便找一条边,然后找剩下n-2个点里面距离这条边最短的一个点,这三点就构成了符合要求的三角形。。然而。。精度被卡死。 换种思路,随便找两个点P1,P2,找剩下n-2个点中哪一个点与P1,P2形成的三角形面积最小,这三点构成了符合要求的三角形,然而我没写。。 最终这样写的,按X,Y进
阅读全文
摘要:只要找出当前没用过的数字中,大于或等于当前这一列的最大值就可以 #include<cstdio> #include<cstring> #include<cmath> #include<vector> #include<algorithm> using namespace std; const int
阅读全文
摘要:水题,先都合成2,看看有没有1多的,有的话存起来,再把那些2合成3,看看有没有多的2,有的话再存起来。。。一直这样下去 #include<cstdio> #include<cstring> #include<cmath> #include<vector> #include<algorithm> us
阅读全文