摘要:
BZOJ_2059 本来打算想想费用流的,但是既然给的是直线,八成就是让dp了,否则完全可以给成图的。 不妨用f[i][j]表示递推到第i个商店时,在前i-1个商店一共买了j的饲料,这样就有状态转移方程f[i][j]=min{f[i-1][k]+(j-k)*C[i-1]}+j*j,其中0<=j-k<=F[i-1]。这样裸着做的话,复杂度是没法承受的,但如果把min{}里的j拿出来的话就会得到f[i][j]=min{f[i-1][k]-k*C[i-1]}+j*C[i-1]+j*j,这样min里面的只和k有关,而且k是要满足一定范围的,这时我们可以用单调队列来维护f[i-1][k]-k 阅读全文
摘要:
BZOJ_2097 像这种最大值最小或者最小值最大的问题,二分答案也许是个不错的选择。二分答案之后问题就变成了对于当前这个树,最少需要删掉几条边才能使各个子树最大的半径都小于或等于某个值,如果删掉的边的数量比S小或者和S相等,那么就有可能使各个子树最大的直径小于或等于一个更小的值。 至于最少删几条边才能使各个子树的最大的直径都小于或等于某个值,可以在dfs的时候利用贪心的思想解决。#include<stdio.h>#include<string.h>#include<vector>#include<algorithm>#include<qu 阅读全文
摘要:
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)); ... 阅读全文