摘要: 思路:建出虚树然后treedp即可,f[i]表示将以i为根的子树与根隔绝的最小代价,f[i]=min(val[i],Σf[son[i]])(val[i]表示将点i与根隔绝的代价),需要注意的是如果i就是关键点那么f[i]=val[i]。 阅读全文
posted @ 2016-10-24 11:51 DUXT 阅读(167) 评论(0) 推荐(0) 编辑
摘要: 思路:首先因为n的范围很大,考虑建立虚树,就是把大部分的冗余的点去掉然后建立一颗新的树然后再树形dp,具体实现可以考虑用一个栈维护,首先求出每个点的dfn然后按照dfn排序,然后用一个栈维护(栈里存的关键点或关键点之间的lca或关键点lca的lca等等。。。),然后枚举关键点,求出关键点与当前栈顶元 阅读全文
posted @ 2016-10-24 10:55 DUXT 阅读(143) 评论(0) 推荐(0) 编辑
摘要: 思路:首先这道题可以直接裸上树剖。 然后参见了黄学长的博客发现了一种更为高明的解法,可以在树上差分,令x为路径(u,v)的lca,然后f[u]++,f[v]++,f[x]--,f[fa[x]]--,然后直接一遍dfs累加起来就好了。(为什么我的代码常数辣么大。。。差分被树剖虐。。。。) 阅读全文
posted @ 2016-10-23 20:00 DUXT 阅读(163) 评论(0) 推荐(0) 编辑
摘要: 思路:首先先求出以1为根的答案,然后考虑由i转移到i的儿子的答案的变化,显然以son[i]为根的子树的所有结点的深度都会减一,其余的点的深度都会加一,然后就可以直接O(n)求出所有结点的答案,然后取max更新答案即可。 #include<iostream> #include<cstdio> #inc 阅读全文
posted @ 2016-10-23 19:55 DUXT 阅读(172) 评论(0) 推荐(0) 编辑
摘要: 思路:状压dp,设f[i][j]表示当前已经选出的牛的状态为i,最后一头选出的牛为j的方案数。 然后注意就是初值不能是f[0][i]=1,因为所有牛本来都可以第一个被选中,然而这样一定初值有些牛可能就无法被第一个选出了,因此应该是f[(1<<i)][i]=1。 #include<iostream> 阅读全文
posted @ 2016-10-23 19:51 DUXT 阅读(220) 评论(0) 推荐(0) 编辑
摘要: 思路:状压dp,枚举疾病的集合,然后判断一下可行性即可。 #include<bits/stdc++.h> using namespace std; #define maxs 400000 #define maxn 1900 int n,d,k; int a[maxn],f[maxs],num[max 阅读全文
posted @ 2016-10-23 19:47 DUXT 阅读(238) 评论(0) 推荐(0) 编辑
摘要: 思路:状压dp,f[i][j]表示新的排列的状态为i(也就是新的排列已经选了哪些数),然后模d的余数为j的方案数。 但考虑到可能有些数会出现多次,假设一个数x出现了cnt[x]次,那么对于一个可行的答案,显然也包含cnt[x]个x,那么这样的答案就会被计算多次,因为如果状态i先加入第一个x再加入第二 阅读全文
posted @ 2016-10-23 19:44 DUXT 阅读(310) 评论(0) 推荐(0) 编辑
摘要: 思路:看到n十分于是考虑状压dp,先预处理出处于状态s的情况下过桥的时间和重量,然后枚举状态转移即可,f[i]=min(f[i],f[j]+time[i^j])(j∈i)(自称会状压dp结果连枚举非空子集都不会的我。。。。。) 顺便普及如何枚举非空子集:for (int j=i;j;j=j&(i-1 阅读全文
posted @ 2016-10-23 19:33 DUXT 阅读(187) 评论(0) 推荐(0) 编辑
该文被密码保护。 阅读全文
posted @ 2016-10-17 09:57 DUXT 阅读(9) 评论(0) 推荐(0) 编辑
摘要: A:题意:给定一个由字母表组成的首尾相接的环,环上有一个指针,最初指向字母a,每次可以顺时针或逆时针旋转一格,例如a顺时针转到z,逆时针转到b,然后问转出给定字符串最少需要转多少次。 思路:模拟。 1 #include<iostream> 2 #include<cstdio> 3 #include< 阅读全文
posted @ 2016-10-17 09:07 DUXT 阅读(252) 评论(0) 推荐(0) 编辑