Mice and Holes 单调队列优化dp
Mice and Holes 单调队列优化dp
n个老鼠,m个洞,告诉你他们的一维坐标和m个洞的容量限制,问最小总距离。1 ≤ n, m ≤ 5000。
 首先列出朴素的dp方程:\(f[i][j]=min(f[i-1][k]+s[j]-s[k])\),其中\(f[i][j]\)表示前i个洞,有j个老鼠进洞。s[j]-s[k]表示第k+1到j个老鼠进洞的路径和。然后我们发现,\(f[i][j]\)的值取决于最小的\(f[i-1][k]-s[k]\ (k<=j)\),同时,j-k必须小于等于第i个洞的容量。于是我们建一个单调队列,队列存储最优的k。然后如果\(j-q[head]\)大于第i个洞的容量,那么head++,然后如果\(f[i-1][j]\)大于队列末尾,那么就一直tail--。这样就可以把\(O(n^3)\)的时间复杂度优化成O(n^2)。
 对了,初始化的时候要注意,想清楚没有优化的时候是什么样的状态。其实不难的。
#include <cstdio>
#include <cstring>
#include <algorithm>
typedef long long LL;
const LL maxn=5005, INF=1e18;
inline LL abs(LL x){ return x<0?-x:x; }
struct Hole{
    LL pos, cap;
    void set(LL x, LL y){ pos=x; cap=y; }
}hole[maxn];
bool cmp(const Hole &a, const Hole &b){
    return a.pos<b.pos; }
//queue:当前第i个洞里面关于有几个老鼠的单调队列
LL n, m, head, tail, queue[maxn];
LL mice[maxn], pre[maxn];
LL fpre[maxn], fnow[maxn], s[maxn];
int main(){
    scanf("%lld%lld", &n, &m);
    for (LL i=1; i<=n; ++i)
        scanf("%lld", &mice[i]);
    std::sort(mice+1, mice+n+1);
    for (LL i=1; i<=m; ++i)
        scanf("%lld%lld", &hole[i].pos, &hole[i].cap);
    std::sort(hole+1, hole+m+1, cmp);
    //pre:洞最多可容纳老鼠的前缀和
    pre[1]=hole[1].cap;
    for (LL i=2; i<=m; ++i)
        pre[i]=pre[i-1]+hole[i].cap;
    if (pre[m]<n){
        printf("-1\n");
        return 0;
    }
    fpre[0]=fnow[0]=0;
    for (int j=1; j<=n; ++j)
        fpre[j]=fnow[j]=INF;
    for (LL i=1; i<=m; ++i){
        //si:前i个老鼠都放在此洞中的代价
        s[0]=0;
        for (LL j=1; j<=n; ++j)
            s[j]=s[j-1]+abs(hole[i].pos-mice[j]);
        head=0; tail=0;
        for (LL j=0; j<=n; ++j){
            //放不进去,那显然是直接跳过
            if (j>pre[i]) break;
            //不能让这个洞容纳更多老鼠
            while (head<tail&&j-queue[head]>hole[i].cap) ++head;
            //单调队列,不是min的通通吃掉
            while (head<tail&&fpre[j]-s[j]<=
                   fpre[queue[tail-1]]-s[queue[tail-1]]) --tail;
            queue[tail++]=j;
            fnow[j]=fpre[queue[head]]+s[j]-s[queue[head]];
        }
        for (LL j=0; j<=n; ++j)
            fpre[j]=fnow[j];
    }
    printf("%lld", fnow[n]);
}
												
											Mice and Holes 单调队列优化dp的更多相关文章
- 单调队列优化DP,多重背包
		
单调队列优化DP:http://www.cnblogs.com/ka200812/archive/2012/07/11/2585950.html 单调队列优化多重背包:http://blog.csdn ...
 - bzoj1855: [Scoi2010]股票交易--单调队列优化DP
		
单调队列优化DP的模板题 不难列出DP方程: 对于买入的情况 由于dp[i][j]=max{dp[i-w-1][k]+k*Ap[i]-j*Ap[i]} AP[i]*j是固定的,在队列中维护dp[i-w ...
 - hdu3401:单调队列优化dp
		
第一个单调队列优化dp 写了半天,最后初始化搞错了还一直wa.. 题目大意: 炒股,总共 t 天,每天可以买入na[i]股,卖出nb[i]股,价钱分别为pa[i]和pb[i],最大同时拥有p股 且一次 ...
 - Parade(单调队列优化dp)
		
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2490 Parade Time Limit: 4000/2000 MS (Java/Others) ...
 - BZOJ_3831_[Poi2014]Little Bird_单调队列优化DP
		
BZOJ_3831_[Poi2014]Little Bird_单调队列优化DP Description 有一排n棵树,第i棵树的高度是Di. MHY要从第一棵树到第n棵树去找他的妹子玩. 如果MHY在 ...
 - 【单调队列优化dp】 分组
		
[单调队列优化dp] 分组 >>>>题目 [题目] 给定一行n个非负整数,现在你可以选择其中若干个数,但不能有连续k个数被选择.你的任务是使得选出的数字的和最大 [输入格式] ...
 - [小明打联盟][斜率/单调队列 优化dp][背包]
		
链接:https://ac.nowcoder.com/acm/problem/14553来源:牛客网 题目描述 小明很喜欢打游戏,现在已知一个新英雄即将推出,他同样拥有四个技能,其中三个小技能的释放时 ...
 - 单调队列以及单调队列优化DP
		
单调队列定义: 其实单调队列就是一种队列内的元素有单调性的队列,因为其单调性所以经常会被用来维护区间最值或者降低DP的维数已达到降维来减少空间及时间的目的. 单调队列的一般应用: 1.维护区间最值 2 ...
 - BZOJ1791[Ioi2008]Island 岛屿 ——基环森林直径和+单调队列优化DP+树形DP
		
题目描述 你将要游览一个有N个岛屿的公园.从每一个岛i出发,只建造一座桥.桥的长度以Li表示.公园内总共有N座桥.尽管每座桥由一个岛连到另一个岛,但每座桥均可以双向行走.同时,每一对这样的岛屿,都有一 ...
 
随机推荐
- selenium-查看selenium API
			
pydoc是Python自带的模块,主要用于从python模块中自动生成文档,这些文档可以基于文本呈现的.也可以生成WEB 页面的,还可以在服务器上以浏览器的方式呈现! 一.pydoc 1.到底什么是 ...
 - bootstrap-自定义导航栏隐藏参数@screen-sm
			
导航菜单默认在屏幕小于768px的时候自动折叠,怎么自定义这个大小? 需要重新编译bootstrap 编译 CSS 和 JavaScript 文件 问题解决!
 - 解决编译warning:warning: ‘MeteringUnit::voltage_gain_’ will be initialized after [-Wreorder]
			
问题: 环境:ubuntu 12.04,g++版本4.6.3,编译目标文件时出现warnings: u1204@u1204-zhw:~/hwsvn/2sw/4prj_mips/UCP_rt5350/s ...
 - DP小合集
			
1.Uva1625颜色的长度 dp[i][j]表示前一个串选到第i个 后一个串选到第j个 的最小价值 记一下还有多少个没有结束即dp2 记一下每个数开始和结束的位置 #include<cstdi ...
 - NOIp2018集训test-10-18 (bike day4)
			
这是一套简单题,这几天的考试让bike老爷感觉很绝望,说实话我也确实不知道还能怎么更简单了. 这几天的题换做llj.sxy应该都能轻松AK吧,至少随便考个250+应该不是问题吧,我越来越觉得觉得我跟他 ...
 - 【Sublime Text 3】编译环境
			
1.默认编译时总会出现错误 报错: [Finished in 1.3s with exit code 1][cmd: ['gcc', 'V:\\Cynthia\\01.c']][dir: V:\Cyn ...
 - Boilerplate
			
HTML5 Boilerplate 是一个由 Paul Irish(Google Chrome 开发人员.jQuery 项目成员.Modernizr 作者.yayQuery 播客主持人)主导的“前端开 ...
 - 【转】 Pro Android学习笔记(六四):安全和权限(1):签发apk
			
目录(?)[-] Android安全模型 数字证书签发 Debug的keystore 生产unsigned的apk 为apk进行证书签发 align安装包 使用Export Wizard生成签发的ap ...
 - 【转】 Pro Android学习笔记(六三):Preferences(7):代码控制首选项
			
[-] 代码实现preference 利用preference保存状态 DialogPreference 代码实现preference View可以不通过xml进行设置,有代码直接进行设置,首选项pr ...
 - angular-cli.json配置参数解析,常用命令解析
			
1.angular-cli.json配置参数解析 { "project": { "name": "ng-admin", //项目名称 &qu ...