Online Judge:Bzoj1761

Label:区间Dp

题目描述

在一条直线上有N个点,每个点M升水. 一个虫子在坐标轴0点上,它每个单位时间移动一格,每个点的水每单位时间消失1升. 问虫子最多可以喝到多少水,喝水的时间忽略不计。

输入

第一行给出数字N,M

下面N行给出N个点的坐标Xi

\(0≤n≤300\), \(1≤m≤1,000,000\),$ −10,000 ≤ x1, x2, . . . , xn ≤ 10,000$

输出

最多可以喝到多少水。

样例

Input

3 15
6
-3
1

Output

25

Hint

虫子开始在0点,它先到1这个点喝水,再到-3,再到6.

题解

类似但更为简单的一道题:USACO2005 nov [Grazing on the Run]

本题题解将基于上面这道的题解来bb,没做过可以先去看这题。

上面那个问题其实求的是:

你的初始坐标为x,你要去数轴上的n个点,每个点原有无限水量。每秒每个点都会少掉一单位水,问遍历完所有点,浪费的最少水量是多少?

而现在我们求的是最多能喝到多少水,而且不一定需要遍历所有点(因为可能你到那了水已经没了,等同于没去遍历)。

假设我们上面那道题求出结果为\(f[1][n]\),难道这道题答案就是\(M*N-f[1][n]\)吗?看起来好像没有问题,似乎是总的水量-浪费的水量,但是,我们上面求出的dp值计算的是所有点的浪费总水量和,但本题中如果我们只考虑去区间\([l,r](l!=1||r!=n)\)则浪费水量会多计了,答案自然不正确。

如何避免这个问题呢?观察数据范围,上面那题\(n<=1000\),而这题\(n<=300\),似乎暗示我们可以再枚举一维:)

我们现在不知道最终走过的区间长度,那就去枚举它,这样我们就可以确定水的总量,从而可以确定每秒浪费的水量(不在我这个区间内的点我就不管它了)。剩下的部分就跟上面那道题一模一样了。

综上,时间复杂度为\(O(N^3)\)。

完整代码如下

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=305,INF=0x3f3f3f3f;
int a[N],dis[N][N],ans,f[N][N][2];
int n,m;
inline void Do(int &x,int y){(x>y)&&(x=y);}
signed main(){
scanf("%lld%lld",&n,&m);
for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
a[++n]=0;
sort(a+1,a+n+1);
for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)dis[i][j]=abs(a[i]-a[j]);
int st=lower_bound(a+1,a+n+1,0)-a;
for(int tot=1;tot<=n;tot++){//枚举最终走过区间长度
memset(f,0x3f,sizeof(f));
f[st][st][0]=f[st][st][1]=0;//注意每次都要初始化
for(int i=1;i<=tot;i++)for(int l=1;l+i-1<=n;l++){
int r=l+i-1;
if(f[l][r][0]<INF){
if(l!=1)Do(f[l-1][r][0],f[l][r][0]+dis[l-1][l]*(tot-i));
if(r!=n)Do(f[l][r+1][1],f[l][r][0]+dis[l][r+1]*(tot-i));
}
if(f[l][r][1]<INF){
if(l!=1)Do(f[l-1][r][0],f[l][r][1]+dis[r][l-1]*(tot-i));
if(r!=n)Do(f[l][r+1][1],f[l][r][1]+dis[r][r+1]*(tot-i));
}
}
for(int i=1;i+tot-1<=n;i++){//此时喝到水量=(区间总水量-区间浪费水量)
ans=max(ans,(tot-1)*m-min(f[i][i+tot-1][0],f[i][i+tot-1][1]));
}
}
printf("%lld\n",ans);
}

[Baltic2009]beetle【区间Dp】的更多相关文章

  1. bzoj 1761: [Baltic2009]beetle 区间dp

    1761: [Baltic2009]beetle Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 255  Solved: 92[Submit][Statu ...

  2. 区间DP复习

    区间DP复习 (难度排序:(A,B),(F,G,E,D,H,I,K),(C),(J,L)) 这是一个基本全在bzoj上的复习专题 没有什么可以说的,都是一些基本的dp思想 A [BZOJ1996] [ ...

  3. [USACO2005 nov] Grazing on the Run【区间Dp】

    Online Judge:bzoj1742,bzoj1694 Label:区间Dp 题目描述 John养了一只叫Joseph的奶牛.一次她去放牛,来到一个非常长的一片地,上面有N块地方长了茂盛的草.我 ...

  4. 【BZOJ-4380】Myjnie 区间DP

    4380: [POI2015]Myjnie Time Limit: 40 Sec  Memory Limit: 256 MBSec  Special JudgeSubmit: 162  Solved: ...

  5. 【POJ-1390】Blocks 区间DP

    Blocks Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 5252   Accepted: 2165 Descriptio ...

  6. 区间DP LightOJ 1422 Halloween Costumes

    http://lightoj.com/volume_showproblem.php?problem=1422 做的第一道区间DP的题目,试水. 参考解题报告: http://www.cnblogs.c ...

  7. BZOJ1055: [HAOI2008]玩具取名[区间DP]

    1055: [HAOI2008]玩具取名 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1588  Solved: 925[Submit][Statu ...

  8. poj2955 Brackets (区间dp)

    题目链接:http://poj.org/problem?id=2955 题意:给定字符串 求括号匹配最多时的子串长度. 区间dp,状态转移方程: dp[i][j]=max ( dp[i][j] , 2 ...

  9. HDU5900 QSC and Master(区间DP + 最小费用最大流)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5900 Description Every school has some legends, ...

随机推荐

  1. NX二次开发-UFUN新建工程图UF_DRAW_create_drawing

    NX9+VS2012 #include <uf.h> #include <uf_draw.h> #include <uf_part.h> UF_initialize ...

  2. LeetCode 1037. Valid Boomerang (有效的回旋镖)

    题目标签:Math 题目给了我们三个点,让我们判断这三个点是否在一条直线上. 利用斜率 k = (y1 - y0) / (x1 - x0) 来判断,如果 三个点 abc, ab 的斜率 = bc 的斜 ...

  3. bootstrap中container和container-fluid的区别

    container和container-fluid 在bootstrap中,两者都是设置文本居中,但是它们还是有很大差别的 container 是随屏幕宽度的变化而变化的,是阶段性变化,有一个随浏览器 ...

  4. ncurses库的介绍与安装

    Frm: http://blog.csdn.net/Mary_Jane/article/details/50769631 介绍 ncurses(new curses)是一套编程库,它提供了一系列的函数 ...

  5. IPv6 三个访问本地地址的小Tips

    最近发现家里宽带支持IPv6了,这里分享三个利用IPv6访问本地地址(内网地址)的方法. 通常来说,我们用localhost来代表本地地址127.0.0.1.其实在IPv6中有他自己的表示方法ip6- ...

  6. 7.spark运行模式

    sparkbin目录下     ./pyspark --help       http://spark.apache.org/docs/latest/submitting-applications.h ...

  7. Python自学:第五章 使用range( )创建数字列表

    # -*- coding: GBK -*- number = list(range(1,6)) print(number) 输出为: [1, 2, 3, 4, 5] 2. # -*- coding: ...

  8. p分位数的原理及计算

    p分位数的原理及计算 大纲>> 1.统计上的分位数概念   2.分位数的计算方法及举例 2.1首先确定p分位数的位置(依据项数分为基数.偶数情况) 2.2 求上一步确定的p分位数位置处的具 ...

  9. Tool Zip 破解

    //侵权请联系我进行删除 email:YZFHKM@163.com 0x00 fcrackzip简单介绍 fcrackzip是一款专门破解zip类型压缩文件密码的工具,工具小巧方便.破解速度快,能使用 ...

  10. JavaScript工作原理

    HTML代码所表示的文档是一种静态文档,几乎没有交互功能,很难使页面成为动态页面.增加脚本语言,可使数据发送到服务器之前先进行处理和校验,动态地创建新的Web内容,更重要的是,引入脚本语言使我们有了事 ...