摘要:
BZOJ_2099 一个可行的贪心思路就是,每次都让这刀切出的串越长越好,然后下一次再从上一刀末尾后面那个字符开始,继续这样贪心地去切。 这样就要反复查询,从某个位置开始,最长能有多少个连续的字符满足是文章中的一个子串,这一点可以将文章建立后缀自动机后来查找,整体查找的复杂度是O(N)的。#include<stdio.h>#include<string.h>#define MAXD 50010struct SufAuto{ int pre, next[26], len; void init() { memset(next, 0, sizeof(next)); ... 阅读全文
摘要:
BZOJ_2621 由于物品不多,可以直接搜过去。对于当前一个物品,无非有两种决策,要么放到前面的某些背包里,要么新开辟一个背包,另外再判断一下当前的背包数是不是已经超过了或者等于最优解来剪一下枝。#include<stdio.h>#include<string.h>#include<algorithm>#include<queue>#define INF 0x3f3f3f3fint N, W, a[20], ANS, r[20];void dfs(int dep, int n){ if(n >= ANS) return; if(dep = 阅读全文
摘要:
RQNOJ_62 我们可以将牌在相邻堆之间的移动想象成经过了一条边,那么任意两堆相邻的牌之间都会有一条边,而且在最优情况下每条边应当是至多经过一次的,如果超过一次的话也可以通过相消变成至多经过一次。那么如何确定一条边要不要被走呢?实际上对于任意一条边来讲,都将牌划分成了左右两部分,如果两部分各自内部不能平衡的话就会通过这条边来达到平衡的目的。这样扫一遍前缀和就可以判定有多少条边需要经过了,而经过的边的数量就是最后的结果。至于可行性,由于最后需要经过的边都是有向的,所以会形成一个有向图,按有向图的方向移动牌即可。#include<stdio.h>#include<string. 阅读全文
摘要:
BZOJ_2582 首先来说,如果一个连通块里面的边的数量EN如果大于点的数量VN的话,那么显然是没办法保证每条边都属于一个顶点的,于是接下来就只剩两种情况要讨论了,一种是EN==VN,一种是EN==VN-1。 如果EN==VN,说明这个连通块里存在一个环,而环上的点是必须要选环上的边的,否则环上的边就会剩下,这样不妨把环拿下来,这时就会发现剩下的部分的分配方案是唯一的,而环这部分的分配方案是有且只有2种的。 如果EN==VN-1,可能着眼于哪个点拥有哪条边不是那么好计算,但换个思路就会非常清晰了,由于VN<EN,那么最后会有一个孤立点,我们不妨考虑这个孤立点是哪个点,而一旦确定某个点是 阅读全文
摘要:
BZOJ_2021 首先一个贪心的思路就是,如果需要大奶酪,那么一定把大的放在上面,而且是把高度最小的大奶酪放在最上面。因此我们可以现将奶酪排个序,把小奶酪放下面,大奶酪放上面,而且大奶酪较矮的放在最上面。 接着考虑放奶酪的决策,如果不用大奶酪的话自然就是一个裸的背包问题,如果用大奶酪就会涉及到一个问题,就是最上面的奶酪是原高,其余的都是原高的4/5,这时可以多加一个bit表示现在奶酪是不是已经“封顶”了,在“封顶”之前高度都按4/5算,“封顶”时按原高算即可。#include<stdio.h>#include<string.h>#include<algorith 阅读全文
摘要:
BZOJ_2580 可以先将字典树建出来并补成trie图,然后就可以用f[i][j]表示第i步走到第j个节点的时一共生成了多少个串,至于走到一个节点时会新增多少个串可以预处理出来,这样在trie图上进行dp即可。#include<stdio.h>#include<string.h>#include<algorithm>#define MAXD 310#define MAXK 1010#define inf 0xc3c3c3c3int N, K, next[MAXD][3], num[MAXD], e, f[MAXK][MAXD], q[MAXD], P[MA 阅读全文
摘要:
BZOJ_2591 由于K比较小,我们可以用f[i][j]表示距离第i个节点为j的所有节点的权值和,那么最后实际上就是对于特定的i输出sum{f[i][j]}。 对于一个特定的f[i][j]来讲,一共由两部分构成,一部分路径来自于子节点,一部分路径来自于父节点,我们可以先从叶子节点开始向上dp,将来自于子节点的部分计算出来,再从根节点开始向下dp,将来自于父节点的部分累加上。#include<stdio.h>#include<string.h>#define MAXD 100010#define MAXM 200010int N, K, first[MAXD], e, 阅读全文
摘要:
BZOJ_2199 这个题目可以枚举每个方案是Y还是N,然后用2-SAT判断是否可以the bills are to be passed or not in such a way that every cow gets her way on at least one of her votes,整体复杂度是O(N*M)的。#include<stdio.h>#include<string.h>#include<algorithm>#define MAXN 2010#define MAXM 8010int N, M, one[MAXM], two[MAXM], f 阅读全文
摘要:
BZOJ_2200 这个题目一看就知道SPFA可做,但是SPFA就是超时…… USACO上给出的解法的大致意思是:由于每条航线都是单向的,而且不存在从航线的终点辗转到航线起点的通路,那么就是说航线将原图分成了若干个相对封闭的区域,我们把航线从原图中拿掉后,剩下的就应当是若干个连通块。由于每个连通块中只有非负权边,那么我们就可以在连通块内用Dijkstra求最短路了。而且从S开始做最短路时,这些连通块是有一定的拓扑关系的,也就是说只有先确定了S到某些连通块中的点的最短路,才能确定S到另一些连通块中的点的最短路,这样按连通块的拓扑顺序,一个连通块一个连通块的不断地求最短路,就可以得到S到每个点的最 阅读全文
摘要:
BZOJ_2272 可以用f[i][j][k]表示递推到第i个字符时,大写字符已经有了j个,且最后一个字符是k,这样总状态一共约有500*250*52,总的状态转移次数约有500*250*200,是可以承受的。#include<stdio.h>#include<ctype.h>#include<string.h>#include<vector>#define MOD 97654321int N, U, L, P, f[2][260][128];std::vector<int> g[128];void init(){ N = U + L 阅读全文