主要是利用了反证法:假设 s-t这条路径为树的直径,或者称为树上的最长路现有结论,从任意一点u出发搜到的最远的点一定是s、t中的一点,然后在从这个最远点开始搜,就可以搜到另一个最长路的端点,即用两遍广搜就可以找出树的最长路证明:1 设u为s-t路径上的一点,结论显然成立,否则设搜到的最远点为T则dis(u,T) >dis(u,s) 且 dis(u,T)>dis(u,t) 则最长路不是s-t了,与假设矛盾2 设u不为s-t路径上的点 首先明确,假如u走到了s-t路径上的一点,那么接下来的路径肯定都在s-t上了,而且终点为s或t,在1中已经证明过了 所以现在又有两种情况了: 1:u.. Read More
hdu 1561 The more, The Better树形DP入门 利用分组背包的思想#include<cstdio>#include<vector>#include<cstring>using namespace std;int dp[250][250];vector<int> edge[250];int n,m;int val[250];int max(int a,int b){ return a>b?a:b;}/*/////////////////////////////////////////////分组背包:for 所有的组i Read More
题目链接http://www.codeforces.com/contest/11/problem/D题目的点数不超过20,所以利用状态压缩DP可解dp[i][j]表示i状态时以j结尾的简单路径的数量,i的二进制表示中为1的表示这个点在路径中i的二进制中最低位1表示的点是起始点View Code #include<cstdio>#include<cstring>typedef __int64 lld;const int maxn = 19;lld dp[1<<maxn][maxn];//int mp[maxn][maxn];int main(){ int n, Read More
求出所有的交点,去重,如果是警察点,就不放入点集再把不在线段交点上的警察点加入点集,排序由于一个点只能和同一线段上相邻的点连边,所以枚举每条直线,相邻的点如果不是警察,建边最后bfs判断能否搜到即可View Code #include <math.h>#include <cstdio>#include <vector>#include <queue>#include<algorithm>using namespace std;const int maxn = 10001;const double eps = 1e-8;inline d Read More
先mark,题目刷的差不多再说View Code #include<cstdio>#include<cstring>#define FF(i,to) for(i=0;i<to;i++)const int MM = 1000005,NC = 26;int N;char str[1000005];struct trie{ int ch[NC],fail,f,val; void init(){ memset(ch,0,sizeof(ch)); fail=f=val=0; }}a[MM];int cnt,rt,q[MM],front,last;void I... Read More
我设计的状态及转移过程dp[i][j]代表前i分钟最多走j次所能获得苹果的最大值则可以由 前i-1分钟最多走j次 前i-1分钟最多走j-1次 这两个状态转移过来注意,第二种的转移第j次可以选择走或者不走。因为是最多走j次跟以前做过的一个树形DP神似View Code #include<cstdio>#include<cstring>int dp[1010][35];int num[1010];int max(int a,int b){ return a>b?a:b;}int main(){ int T,W,i,j; while(scanf("%d%d&q Read More
题目链接http://www.codeforces.com/problemset/problem/145/E蛮好的题目一连串由4、7组成的字符串两种操作:count 输出整个区间内最长的不下降子序列的长度switch a b 将a、b之间的数4变成7 7变成4注意,最长不下贱子序列不一定要连续一般情况下,不连续的最长不下降子序列的长度是无法维护的,但是这道题目的特殊性显而易见,只有4 7 两种数字,相当于0 1做法:1:分别记录区间最长不下降和最长不上升的序列的长度,这样子进行异或操作的时候可以直接互换2:记录区间0的个数和1的个数,利用这两个信息可以 在将信息往上传的时候 维护区间最长的.. Read More
可以用来锻炼线段树基本功这种题思路基本不用怎么想,固定好代码框架,往里面填代码就好了,但要绝对仔细因为有异或操作,所以要把白色和黑色的信息都记录下来,在更新的时候可以互换View Code #include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1const int maxn = 111111;int sum[maxn<<2];int lb[m Read More
因为题目告诉我们每两点间只有一条路相连that there is exactly one path between any two free blocks.就可以把点之间形成的路径看成是一棵树题目又要我们找最长的一条路,瞬间就可以转换成树的最长路来做了结论是从树上的任何一点出发,能搜到的最远的点肯定是最长链上的一端,再从这一端出发,能搜到的最远的点的距离即为答案证明过程详见View Code #include<queue>#include<cstdio>#include<cstring>#include<algorithm>using names Read More
上图使用来描述直线向内推进r这一过程的ac=r,ae是推进前的直线上的两点,现在求c、f的坐标,由上可得三角形ace 与三角形abd相似,所以很快便可求出ab 的距离,即x坐标的移动距离,延长de,从f向其做垂线,连接fd,便又可以由三角形相似求得y坐标的移动距离下面是两道半平面交向内推进r的例子http://poj.org/problem?id=3525http://poj.org/problem?id=3384主要讲讲3384先用3525的方法向内推进r求出一个内核,则可知这个核上的任何一点都可以成为圆心坐标,要使的两个圆的重叠面积尽可能小,就要使他们的圆心坐标尽可能的远,素以可以选取内核 Read More