cstring

codeforces 1288C. Two Arrays(dp)

孤人 提交于 2020-05-02 03:27:45
链接:https://codeforces.com/contest/1288/problem/C C. Two Arrays 题意:给定一个数n和一个数m,让构建两个数组a和b满足条件,1.数组中所有元素的取值在1~n之间,a和b数组长度是m。2. a数组是单调不递减的,b数组是单调不递增 3. 任意的位置i,有a i <=b i 思路:可以组合数学做,也可以dp,以下为dp做法。首先如果把a、b两个数组合并成 a 1 ,a 2 ,a 3 ,.......a m ,b m ,b m-1 ,b m-2 ,b m-3 ...........b 3 ,b 2 ,b 1, 会发现整个数列是单调不递减的,那么就可以dp做了, dp[i][j]表示第i个位置可以放 大于等于 j 的方案数 ,那么转移方程就是 dp[i][j] = dp[i-1][j] + dp[i][j+1] AC代码: 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 #include<queue> 7 using namespace std; 8 typedef long long ll; 9 const int maxm = 12 ; 10 const int

YBT 5.4 状态压缩动态规划

蓝咒 提交于 2020-05-02 00:40:54
#loj 10170. 「一本通 5.4 例 1」骑士 看数据范围n<=10,所以不是搜索就是状压dp,又因为搜索会超时所以用dp dp[i][k][j]表示现已经放到第i行,前面共有k个,这一行状态为j so,dp[i][k][j]=dp[i-1][k-num[j]][t] #include<iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #define low_bit(x) x&-x; using namespace std; inline long long read() { long long f= 1 ,ans= 0 ; char c; while (c< ' 0 ' ||c> ' 9 ' ){ if (c== ' - ' )f=- 1 ;c= getchar();} while (c>= ' 0 ' &&c<= ' 9 ' ){ans=ans* 10 +c- ' 0 ' ;c= getchar();} return ans* f; } long long dp[ 11 ][ 1001 ][ 1001 ]; // dp[i][j][k]表示前i行放k个且第i行的状态为j long long n,k,s[ 1001 ],num[ 1001 ]; long

Dijkstra再理解+最短路计数

£可爱£侵袭症+ 提交于 2020-05-01 22:10:07
众所周知,Dijkstra算法是跑单源最短路的一种优秀算法,不过他的缺点在于难以处理负权边。 但是由于在今年的NOI赛场上SPFA那啥了(嗯就是那啥了),所以我们还是好好研究一下Dij的原理和它的优化吧。 (前面那篇写的太简陋了) 1.Dijkstra算法的原理 首先,我们先假设整个图已经被建完而且所有边权全部为正。使用dis[i]表示从原点s到i点的最短距离。之后我们从选取的原点s开始,进行到汇点t的最短路搜寻。s一开始就会连向几个顶点,它所能到达的顶点的距离我们更新一 下,而不能到达的顶点的距离就先设为INF。之后,我们在这个点所能到达的所有点之中,找出一个dis最小的点,那么此时,到这个点的最短路径就已经被确定了。 这是为什么呢?因为图中所有边权全部为正,而当前点(u)的dis已经是最小的了,从其他点(v)再到这个点,所经过的距离必然大于dis[u],也就是肯定不是到达u点的最短路。 因此这样我们就可以不断地确定一些点,之后再从确定的点集出发,去确定更多的点,这样就可以找到到汇点t的最短路径长度了。 (我偷了别人的图和文章来演示如何求从顶点v1到其他各个顶点的最短路径) 首先第一步,我们先声明一个dis数组,该数组初始化的值为 : 我们的顶点集T的初始化为:T={v1} 既然是求 v1顶点到其余各个顶点的最短路程,那就先找一个离 1 号顶点最近的顶点。通过数组 dis

2019ccpc秦皇岛/Gym102361 F Forest Program 仙人掌上dfs

家住魔仙堡 提交于 2020-05-01 22:05:17
题意: 某地沙漠化严重,沙漠里长了很多仙人掌,现在要让你删掉仙人掌的一些边让它的所有连通分量都是树,就完成了沙漠绿化(什么鬼逻辑?)让你计算删边的方案数。 仙人掌是一种特殊的图,它的每一条边只属于1或0条回路。 题解: 画几个仙人掌就能明白,仙人掌就是一棵树上的某些点长出了回路,可以把仙人掌分成若干个回路和不属于回路的边,要把仙人掌删成树不难,每个回路至少删掉一条边,即减掉一种所有回路边都不删的的方案,所有非回路边删或不删均可,假设非回路边有$a_0$个,第i个回路有$a_i$条边$(i=1,2....n)$,容易得出方案数是$2^{a_0}*\prod _{i=1}^{n} 2^{a_i}-1$ 难点在于怎样找出仙人掌的所有回路,一种方法是dfs,记录边的深度,一旦从深度高的边dfs到了深度低的边,即找到了一个环,dfs过程中有如下几种情况: 1,dfs到了父亲,不用管,直接continue 2,dfs到了深度比自己浅的点,就是找到了环,环边数为两点深度之差+1,如下图从5到1 3,dfs到了 比自己深度深的点,则是访问到了统计过的环,也不管 4,dfs到了未标记深度的点,将此点深度记为父节点深度+1并从此点开始dfs 此题坑点在于图未必是连通图,需要从每一个未标记深度的点开始dfs #include<iostream> #include <vector> #include

BZOJ1023: [SHOI2008]cactus仙人掌图(仙人掌dp)

天大地大妈咪最大 提交于 2020-05-01 22:02:20
Time Limit: 1 Sec Memory Limit: 162 MB Submit: 3467 Solved: 1438 [ Submit ][ Status ][ Discuss ] Description   如果某个无向连通图的任意一条边至多只出现在一条简单回路(simple cycle)里,我们就称这张图为仙人掌 图(cactus)。所谓简单回路就是指在图上不重复经过任何一个顶点的回路。   举例来说,上面的第一个例子是一张仙人图,而第二个不是——注意到它有三条简单回路:(4,3,2,1,6 ,5,4)、(7,8,9,10,2,3,7)以及(4,3,7,8,9,10,2,1,6,5,4),而(2,3)同时出现在前两 个的简单回路里。另外,第三张图也不是仙人图,因为它并不是连通图。显然,仙人图上的每条边,或者是这张仙 人图的桥(bridge),或者在且仅在一个简单回路里,两者必居其一。定义在图上两点之间的距离为这两点之间最 短路径的距离。定义一个图的直径为这张图相距最远的两个点的距离。现在我们假定仙人图的每条边的权值都是1 ,你的任务是求出给定的仙人图的直径。 Input   输入的第一行包括两个整数n和m(1≤n≤50000以及0≤m≤10000)。其中n代表顶点个数,我们约定图中的顶 点将从1到n编号。接下来一共有m行。代表m条路径。每行的开始有一个整数k(2≤k

几个解决k染色问题的指数级做法

余生长醉 提交于 2020-05-01 21:33:13
几个解决k染色问题的指数级做法                 ——以及CF908H题解 给你一张n个点的普通无向图,让你给每个点染上k种颜色中的一种,要求对于每条边,两个端点的颜色不能相同,问你是否存在一种可行方案,或是让你输出一种可行方案,或是让你求出满足条件的最小的k。这种问题叫做k染色问题。众所周知,当k>2时,k染色问题是NP的。但是相比$O(k^n)$的暴力搜索来说,人们还是找到了很多复杂度比较优越的指数级做法。本文简单介绍其中几种。 因为对于$O(n^22^n)$来说,$O(n^2)$小得可以忽略不计,所以在本文中我们用$O^*(2^n)$来代替$O(n^{...}2^n)$。 三染色问题 k=3的情况显然比其它的情况更容易入手一些,下面给出几种简单的方法: 1.生成树 先任意求出一个原图的生成树,而对一个生成树染色有$3\cdot 2^{n-1}$种方案,所以暴力即可。 2. 转成2分图 3染色问题可以看成将原图分为3个点独立集的问题。而 3个独立集中最小的那个一定不超过$\frac n 3$,所以我们$C_n^{n\over 3}$搜索最小的这部分,然后剩余部分的变成二染色问题,可以在多项式时间内解决。复杂度$\approx O^*({27\over 4})^{n\over 3}\le O^*(1.89^n)$。 3. 随机化+2-SAT 对于每个点

堆优化Dijkstra计算最短路+路径计数

烂漫一生 提交于 2020-05-01 18:46:01
  今天考试的时候遇到了一道题需要路径计数,然而蒟蒻从来没有做过,所以在考场上真的一脸懵逼。然后出题人NaVi_Awson说明天考试还会卡SPFA,吓得我赶紧又来学一波堆优化的Dijkstra(之前只会SPFA。。。     堆优化Dijkstra   其实Dijkstra的思想很简单。SPFA是以边为基础的最短路松弛,那么Dijkstra恰好相反,是以点为基础的最短路松弛。划分两个点的集合,一个是已经松弛的点集合,一个是未松弛的点集合,每次从已松弛的点集合中找当前路径最小的点来松弛与它相连的未松弛的点。但是如果是不加优化的Dijkstra复杂度是$O(n^2)$的,肯定会T,所以这里引入堆优化,复杂度可以降到$O((n+m)\log n)$。   路径计数   路径计数其实也很简单,在做最短路的时候多引入一个数组,表示当前从远点到达该点的最短路径条数。松弛的时候如果发现该点当前的最短路长度和它被松弛得到的长度相等,那么说明到达它的最短路径条数又增加了,那么就把该点的路径条数加上松弛点的路径条数;如果该点的最短路长度小于被松弛的长度,那么就更新最短路,同时更新路径条数,令该点的最短路径条数等于松弛点的路径条数。    模板题   最后再放上自己打的堆优化Dijkstra最短路+路径计数代码。   Code: // It is made by HolseLee on 8th Aug

Ant Trip(欧拉回路+并查集)

末鹿安然 提交于 2020-05-01 11:33:34
Ant Trip 题目描述 原题来自:2009 Multi-University Training Contest 12 - Host by FZU 给你无向图的 N 个点和 M 条边,保证这 M 条边都不同且不会存在同一点的自环边,现在问你至少要几笔才能所有边都画一遍。(一笔画的时候笔不离开纸) 输入格式 多组数据,每组数据用空行隔开。 对于每组数据,第一行两个整数 N,M 表示点数和边数。接下去 M 行每行两个整数 a , b,表示 a,b 之间有一条边。 输出格式 对于每组数据,输出答案。 样例 样例输入 3 3 1 2 2 3 1 3 4 2 1 2 3 4 样例输出 1 2 数据范围与提示 1 ≤ N ≤ 1 0^ 5 , 0 ≤ M ≤ 2 × 1 0 5 , 1<=a,b <=N 思路: It's also a good problem 原图应是由若干个无向连通图组成的 当这个无向连通图只有一个点时,这是一个孤立点,不做操作 当这个无向连通图是一条欧拉回路或欧拉路径时,只需要一笔画即可,sum++; 当这个无向连通图有大于2个奇度点,需要用奇度点的个数的二分之一笔画完,为什么?因为一笔可以消掉两个奇度点。由于对称性的缘故,一条边的左右两端点度数分别加一,倘若原来两点都是奇度点,则两端点都会变成偶度点,反之亦然,倘若两端点度数的奇偶性不同,一者为奇一者为偶

【BZOJ】2125: 最短路 圆方树(静态仙人掌)

随声附和 提交于 2020-05-01 11:29:09
【题意】给定带边权仙人掌图,Q次询问两点间最短距离。n,m,Q<=10000 【算法】圆方树处理仙人掌问题 【题解】树上的两点间最短路问题,常用倍增求LCA解决,考虑扩展到仙人掌图。 先对仙人掌图建圆方树,圆圆边和原图边权一致。对于每个方点代表的环,记深度最小的点为x,则圆方边的边权是圆点到x的最短距离。 若lca(u,v)为圆点,则两点间最短路转化为圆方树上dis[u]+dis[v]-2*dis[lca]。(向上延伸的路径,经过环则必然经过每个方点的x,计算无误) 若lca(u,v)为方点,则记u,v在方点连接的圆点A,B的子树内,那么两点间最短路为dis[u]+dis[v]-dis[A]-dis[B]+dis(A,B),dis(A,B)是A,B在环上的短侧路径。 复杂度O(Q log n)。 实现细节: 1.Tarjan:建圆方树(先处理树边,最后在深度最小处处理环) 2.处理方点:s[i]表示点i从所在环点x(深度最小)开始逆时针的距离,最终s[x]记为s[N]后s[x]=0。另外注意要记录一下环中点的编号顺序。 3.LCA:圆点直接计算,方点中dis(A,B)=min{ s[A]+s[w]-s[B] , s[B]-s[A] }(A在B的顺时针方向,否则交换AB)。 4.注意防止访问父亲的边是i^1,初始tot=1。 #include<cstdio> #include

天梯赛-L1-018. 大笨钟

喜欢而已 提交于 2020-05-01 09:39:18
L1-018. 大笨钟 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 微博上有个自称“大笨钟V”的家伙,每天敲钟催促码农们爱惜身体早点睡觉。不过由于笨钟自己作息也不是很规律,所以敲钟并不定时。一般敲钟的点数是根据敲钟时间而定的,如果正好在某个整点敲,那么“当”数就等于那个整点数;如果过了整点,就敲下一个整点数。另外,虽然一天有24小时,钟却是只在后半天敲1~12下。例如在23:00敲钟,就是“当当当当当当当当当当当”,而到了23:01就会是“当当当当当当当当当当当当”。在午夜00:00到中午12:00期间(端点时间包括在内),笨钟是不敲的。 下面就请你写个程序,根据当前时间替大笨钟敲钟。 输入格式: 输入第一行按照“hh:mm”的格式给出当前时间。其中hh是小时,在00到23之间;mm是分钟,在00到59之间。 输出格式: 根据当前时间替大笨钟敲钟,即在一行中输出相应数量个“Dang”。如果不是敲钟期,则输出: Only hh:mm. Too early to Dang. 其中“hh:mm”是输入的时间。 输入样例1: 19:05 输出样例1: DangDangDangDangDangDangDangDang 输入样例2: 07:05 输出样例2: Only 07:05. Too early to Dang.