[BZOJ 4409] [Usaco2016 Feb]Circular barn
来源:互联网 发布:js登录表单验证 编辑:程序博客网 时间:2024/04/30 05:58
觉得应该正经的写一写做法了 TAT 不能总是玄学啊显然啊意会啊什么的。
为了方便理解…我们不妨认为题意是给牛选k个集合点然后牛逆时针走到这k个点上。
首先是破环成链,嘛,相信大家都会。
然后这一步处理的手段和BZOJ 1096 有点儿像[虽然还没有写那道题], 我们令a[i]表示点i的牛数,sum[i] 表示牛数的前缀和,然后令 b[i] 表示 1 ~ n 的牛全部移动到1的代价。这样做以后有什么好处呢?我们发现 这时候 i ~ j 的牛全部移动到 i 点的代价就是 b[i] - b[j - 1] - (sum[i] - sum[j - 1]) * j ;
然后就好办了,我们枚举环的起始点为 p ,然后枚举正在给牛选第 L 个集合点, 推一推状态转移方程发现是可以斜率优化的,所以我们按顺序每计算一个f[ L ][ i ]; 把 f[L - 1][i] 插入到凸包里。 最后用 f[k - 1][p + n - 1] 更新答案即可;
时间复杂度 O(n ^ 2 * k * log n )
[沙茶不会用markdown…
[A了之后发现斜率也是单调的可以优化成n ^ 2 * k 的但是不管了
[作者编写程序时脑子一片混乱,边界情况可能和上文不太一样….
#include<cstdio>#include<algorithm>using namespace std;typedef long long LL;inline void read(int &x){x=0;char c;while((c=getchar())<'0'||c>'9');for(x=c-'0';(c=getchar())>='0'&&c<='9';x=x*10+c-'0');}const LL inf = 1e16;const int N = 2010 ;struct Point { LL x, y; Point() {} Point(LL x, LL y) : x(x), y(y) {} inline Point operator - (const Point & b) const { return Point(x - b.x, y - b.y); } inline LL operator ^ (const Point & b) const { return x * b.y - y * b.x; }};struct Stack{ Point s[N]; int top; void insert(Point u) { if (u.y <= s[top].y) return; while (top > 1 && ((s[top] - s[top - 1]) ^ (u - s[top])) <= 0) top--; s[++top] = u; }#define calc(p) ((s[(p)].y - s[(p)].x * x)) LL query(LL x) { int l = 1, r = top; while (l < r) { int mid = (l + r) >> 1; if (calc(mid) > calc(mid + 1)) l = mid + 1; else r = mid; } return calc(l); }#undef calc}T;LL sum[N], b[N], f[2][N];int a[N], n, k;int main(){ read(n), read(k); for (int i = 1; i <= n; ++i) read(a[i]), a[i + n] = a[i]; for (int i = 1; i <= n + n; ++i) { sum[i] = sum[i - 1] + a[i]; b[i] = b[i - 1] + a[i] * (i - 1); } LL ret = inf; for (int i = 0, ed = n; i < n; ++i, ++ed) { for (int j = i + 1; j <= ed; ++j) f[0][j] = b[j] - b[i] - (sum[j] - sum[i]) * i; int t = 1; for (int l = 1; l < k; ++l) { T.s[T.top = 0] = Point(i + l, f[t ^ 1][i + l] - b[i + l] + sum[i + l] * (i + l)); for (int j = i + l + 1; j <= ed; ++j) { f[t][j] = T.query(sum[j]) + b[j]; T.insert(Point(j, f[t ^ 1][j] - b[j] + sum[j] * j)); } t ^= 1; } ret = min(ret, f[t ^ 1][ed]); } printf("%lld\n", ret); return 0;}
0 0
- [BZOJ 4409] [Usaco2016 Feb]Circular barn
- BZOJ 4412/Usaco2016 Feb Circular Barn(构造)
- [BZOJ 4412] [Usaco2016 Feb]Circular Barn
- BZOJ4409: [Usaco2016 Feb]Circular barn
- 【贪心】[USACO2016 金组]Circular Barn
- 【动态规划】[USACO2016 金组]Circular Barn Revisited
- USACO 2016 Feb Circular Barn 二分+树状数组
- 【BZOJ】4413: [Usaco2016 Feb]Milk Pails bool型dp
- BZOJ 1696: [Usaco2007 Feb]Building A New Barn新牛舍
- bzoj 1696: [Usaco2007 Feb]Building A New Barn新牛舍
- 【Usaco2016 FEB】Fenced In
- 【Usaco2016 FEB】Load Balancing
- bzoj4412 Circular Barn 构造
- [扫描线 线段树上二分] BZOJ 4411 [Usaco2016 Feb]Load balancing
- 【Usaco2016 FEB】Fenced In 题解
- BZOJ4411: [Usaco2016 Feb]Load balancing
- BZOJ 1696 [Usaco2007 Feb]Building A New Barn新牛舍 数学
- BZOJ[1696][Usaco2007 Feb]Building A New Barn新牛舍 贪心
- 《Java实战开发经典》第六章6.3
- [leetcode 156]Binary Tree Upside Down
- 归并排序(解析及代码实现)
- 2016蓝桥杯假期任务之《翻硬币 》
- win10 UWP MessageDialog 和 ContentDialog
- [BZOJ 4409] [Usaco2016 Feb]Circular barn
- 区间比较equal
- 【leetcode】Array—— Majority Element(169)
- 生成真静态页面
- C++队列、栈的基本用法
- string的常用代码
- 试问蓝桥杯有多水,一道题就能回答你(吐槽,坑)
- javaWeb poi导入excel文件
- 集体智慧编程——搜索与排名-Python实现