poj 3709 K-Anonymous Sequence
来源:互联网 发布:淘宝网名片 编辑:程序博客网 时间:2024/05/22 07:54
http://poj.org/problem?id=3709
/*
O(n^2)的DP方程:f[i]=Min{f[j]+sum[i]-sum[j]-a[j+1]*(i-j)}。
假设决策j1<j2并且j2优于(或者不差于)j1,那么
f[j1]+sum[i]-sum[j1]+a[j1+1]*(i-j1) >= f[j2]+sum[i]-sum[j2]-a[j2+1]*(i-j2)
[(f[j1]-sum[j1]+a[j1+1]*j1) - (f[j2]-sum[j2]+a[j2+1]*j2)] >= i*(a[j1+1]-a[j2+1])。
a[j2+1]>=a[j1+1], 所以a[j1+1]-a[j2+1] <= 0。
可以写成:[(f[j1]-sum[j1]+a[j1+1]*j1) - (f[j2]-sum[j2]+a[j2+1]*j2)] / (a[j1+1]-a[j2+1]) <= i。
对于a[j1+1]==a[j2+1]的情况,不能用除法了,只能用乘法那个表达式,
所以,如果对于决策j1,j2满足上述表达式,则j2 优于 j1。
首先刚开始队首元素为0
用dy(i,j)表示[(f[i]-sum[i]+a[i+1]*i) - (f[j]-sum[j]+a[j+1]*j)]
用dx(i,j)表示(a[i+1]-a[j+1])*i
然后假设队列首尾指针head < tail 并且dy(queue[head],queue[head+1]) >=
i*dx(queue[head],queue[head+1]),那么队首元素直接丢掉就可以了。因为i是递
增的,如果当前queue[head]没有queue[head+1]好,那么今后也不会。
对于队尾的2个原素x, y来说,
如果对于当前i,y比x要差,那么由前面的证明:对于比较大的i,y不一定就比x差,
有可能比x好呢,我们来看看队尾3个元素的情况:x,y,z,如果
dy(x,y)/dx(x,y)>=dy(y,z)/dx(y,z),那么可以直接把y给删了。因为
dy(x,y)/dx(x,y)和dy(y,z)/dx(y,z)是个常数,对于某个i,如果dy(x,y)/dx(x,y)<=i的
话,那么dy(y,z)/dx(y,z)一定也小于等于i,也就是说:如果y优于x,那么z一定优于
y,这个时候留着y就没用了。。。。直接删了。。。
过程就是这些,另外:因为有个限制k,所以决策点需要延迟加
入。
*/
#include <iostream>#include <cstdio>#include <cstring>using namespace std;const int MAXX = 500010;int n, k, queue[MAXX];__int64 sum[MAXX], f[MAXX], a[MAXX];__int64 dy(int j1, int j2){ return (f[j1]-sum[j1]+a[j1+1]*j1) - (f[j2]-sum[j2]+a[j2+1]*j2);}__int64 dx(int j1, int j2){ return (a[j1+1] - a[j2+1]);}void dp(){ int i, j, head, tail, x, y, z; head = tail = 0; queue[0] = 0; for(i = 1; i <= n; i++) { while(head<tail && dy(queue[head], queue[head+1])>=i*dx(queue[head], queue[head+1])) head++; j = queue[head]; f[i] = f[j] + sum[i] - sum[j] - a[j+1]*(i-j); if(i >= 2*k-1) //实际上是i-k+1>=k { z = i-k+1; while(head < tail) { x = queue[tail-1]; y = queue[tail]; if(dy(x,y)*dx(y,z) >= dy(y,z)*dx(x,y)) tail--; else break; } queue[++tail] = z; } }}int main(){ int t, i; scanf("%d", &t); while(t--) { scanf("%d%d", &n, &k); sum[0] = 0; for(i = 1; i <= n; i++) { scanf("%I64d", a+i); sum[i] = sum[i-1] + a[i]; } dp(); printf("%I64d\n", f[n]); } return 0;}
ok!
- poj 3709 K-Anonymous Sequence
- POJ 3709 K-Anonymous Sequence
- POJ 3709 K-Anonymous Sequence
- poj 3709 K-Anonymous Sequence
- POJ 3709 K-Anonymous Sequence 斜率优化
- POJ - 3709 K-Anonymous Sequence(斜率优化)
- POJ 3709 K-Anonymous Sequence(斜率DP)
- POJ 3709 K-Anonymous Sequence 笔记
- poj 3709 K-Anonymous Sequence(斜率优化DP)
- poj 3709 K-Anonymous Sequence 斜率优化dp
- poj 3709 K-Anonymous Sequence 斜率优化dp
- POJ 3709 K-Anonymous Sequence(斜率优化DP)
- POJ 3709 K-Anonymous Sequence (斜率优化DP)
- poj 3709 K-Anonymous Sequence dp斜率优化
- POJ 3709 K-Anonymous Sequence (斜率优化DP)
- POJ 3709 K-Anonymous Sequence (斜率优化DP)
- poj 3709 K-Anonymous Sequence 动态规划+斜率优化
- poj 3709 K-Anonymous Sequence(DP-单调性优化-斜率优化)
- C# 根据名称字符串 求 属性
- Linux下让Eclipse支持Python
- 一篇有意思的招聘帖子
- 字符串相互转换
- hash_map
- poj 3709 K-Anonymous Sequence
- flex java android jquery IT氧吧经典文摘
- java IO 简单应用
- 苹果新专利将Mac天线隐藏在键盘下
- 闲着看看jquery.ajax源码
- 字符串与整形转换
- 二叉树的遍历 非递归 C实现——先序遍历篇
- ★☆ Visual Studio 2008 每日小窍门 【持续发布中~】 Tips:091
- 激情与大学