题目描述

John养了一只叫Joseph的奶牛。一次她去放牛,来到一个非常长的一片地,上面有N块地方长了茂盛的草。我们可以认为草地是一个数轴上的一些点。Joseph看到这些草非常兴奋,它想把它们全部吃光。于是它开始左右行走,吃草。John和Joseph开始的时候站在p位置。Joseph的移动速度是一个单位时间一个单位距离。不幸的是,草如果长时间不吃,就会腐败。我们定义一堆草的腐败值是从Joseph开始吃草到吃到这堆草的总时间。Joseph可不想吃太腐败的草,它请John帮它安排一个路线,使得它吃完所有的草后,总腐败值最小。John的数学很烂,她不知道该怎样
做,你能帮她么?

输入

* Line 1 : Two space-separated integers: N and L. N<=1000
* Lines 2..N+1: Each line contains a single integer giving the position P of a clump (1 <= P <= 1,000,000).

输出

* Line 1: A single integer: the minimum total staleness Bessie can achieve while eating all the clumps.

样例输入

4 10
1
9
11
19

样例输出

44


题解

区间dp,膜拜popoqqq

因为路过的草一定吃,所以吃的草一定是一段区间。

用f[i][k]表示吃完从i开始连续的k堆草,且此时在左侧的最小腐败值,

用g[i][k]表示吃完从i开始连续的k堆草,且此时在右侧的最小腐败值。

这样我们发现腐败值很难求,并且无法保证最优。

所以我们可以先计算出每段时间所有草增加的腐败值,这样既能保证dp的成立,又方便计算。

状态转移方程应该很容易由f/g[i/i+1][k-1]推出来。

由于空间限制,需要用到滚动数组黑科技。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
long long f[1001][2] , g[1001][2] , p[1001];
int main()
{
int n , i , j , k , cl = 0 , cr = 0;
long long m;
scanf("%d%lld" , &n , &m);
for(i = 1 ; i <= n ; i ++ )
scanf("%lld" , &p[i]);
sort(p + 1 , p + n + 1);
for(i = 1 ; i <= n ; i ++ )
{
if(p[i] <= m)
cl = i;
if(!cr && p[i] > m)
cr = i;
}
memset(f , 0x3f , sizeof(f));
memset(g , 0x3f , sizeof(g));
if(cl) f[cl][1] = g[cl][1] = n * (m - p[cl]);
if(cr) f[cr][1] = g[cr][1] = n * (p[cr] - m);
for(k = 2 ; k <= n ; k ++ )
{
for(i = 1 ; i + k - 1 <= n ; i ++ )
{
j = i + k - 1;
f[i][k & 1] = min(f[i + 1][~k & 1] + (n - k + 1) * (p[i + 1] - p[i]) , g[i + 1][~k & 1] + (n - k + 1) * (p[j] - p[i]));
g[i][k & 1] = min(g[i][~k & 1] + (n - k + 1) * (p[j] - p[j - 1]) , f[i][~k & 1] + (n - k + 1) * (p[j] - p[i]));
}
}
printf("%lld\n" , min(f[1][n & 1] , g[1][n & 1]));
return 0;
}

【bzoj1742】[Usaco2005 nov]Grazing on the Run 边跑边吃草 区间dp的更多相关文章

  1. bzoj1742[Usaco2005 nov]Grazing on the Run 边跑边吃草*&&bzoj3074[Usaco2013 Mar]The Cow Run*

    bzoj1742[Usaco2005 nov]Grazing on the Run 边跑边吃草 bzoj3074[Usaco2013 Mar]The Cow Run 题意: 数轴上有n棵草,牛初始在L ...

  2. BZOJ1742: [Usaco2005 nov]Grazing on the Run 边跑边吃草

    数轴上n<=1000个点,从p出发以任意顺序走到所有的点,求到达每个点的时间之和的最小值. 好题!看起来水水的实际易错! 显然的结论是经过一个区间点之后肯定落在左端点或右端点上,谁没事最后还往中 ...

  3. BZOJ 1742: [Usaco2005 nov]Grazing on the Run 边跑边吃草( dp )

    dp... dp( l , r , k )  , 表示 吃了[ l , r ] 的草 , k = 1 表示最后在 r 处 , k = 0 表示最后在 l 处 . ------------------- ...

  4. [Usaco2005 nov]Grazing on the Run 边跑边吃草 BZOJ1742

    分析: 首先,连续选择一段必定最优... 区间DP,f[i][j]表示从i开始,连续j个被吃掉了,并且,牛在i处,g[i][j]则表示在i+j-1处 f[i][j]可以从g[i+1][j]和f[i+1 ...

  5. bzoj 1742: [Usaco2005 nov]Grazing on the Run 边跑边吃草【区间dp】

    挺好的区间dp,状态设计很好玩 一开始按套路设f[i][j],g[i][j]为吃完(i,j)区间站在i/j的最小腐败值,后来发现这样并不能保证最优 实际上是设f[i][j],g[i][j]为从i开始吃 ...

  6. BZOJ1742[Usaco2005 nov]Grazing on the Run

    Description John养了一只叫Joseph的奶牛.一次她去放牛,来到一个非常长的一片地,上面有N块地方长了茂盛的草.我们可 以认为草地是一个数轴上的一些点.Joseph看到这些草非常兴奋, ...

  7. 2018.10.22 bzoj1742: Grazing on the Run 边跑边吃草(区间dp)

    传送门 区间dp入门题. 可以想到当前吃掉的草一定是一个区间(因为经过的草一定会吃掉). 然后最后一定会停在左端点或者右端点. f[i][j][0/1]f[i][j][0/1]f[i][j][0/1] ...

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

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

  9. BZOJ2023: [Usaco2005 Nov]Ant Counting 数蚂蚁

    2023: [Usaco2005 Nov]Ant Counting 数蚂蚁 Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 56  Solved: 16[S ...

随机推荐

  1. 理解C指针: 一个内存地址对应着一个值

    一个内存地址存着一个对应的值,这是比较容易理解的. 如果程序员必须清楚地知道某块内存存着什么内容和某个内容存在哪个内存地址里了,那他们的负担可想而知.    汇编语法对“一个内存地址存着一个对应的数” ...

  2. 成都Uber优步司机奖励政策(3月12日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  3. spring data jap操作

    package com.example.demo; import com.example.entity.UserJ; import com.example.respository.UserJRespo ...

  4. vscode 全透明背景图

    一.前言 08.02更新:已魔改插件 可以直接下载插件使用了 10.18跟新:已发布到vscode扩展  下载地址 下载后手动安装就ok了,具体配置安装后点开插件有说明的!!! 今天看到了博客园 这篇 ...

  5. dubbo入门(一)

    1.简介 Dubbo由阿里巴巴开源,是一个分布式服务框架,致力于提供高性能和透明化的RPC(远程过程调用)远程服务调用方案,以及SOA服务治理方案.如果没有分布式的需求,Dbubbo是不需要的,其本质 ...

  6. eclipse格式化

    一.eclipse格式化的必要性 1.便于阅读 2.便于协作 二.eclipse格式化快捷键 ctrl shift + F

  7. 【循环控制器】-(针对中间部分要循环的场景,相当于loadrunner的action部分)

    一般使用 setup线程组 + teardown组 针对中间要循环的部分   使用循环处理器    单独循环中间的部分,相当于loadrunner的action部分

  8. 【机器学习】线性回归python实现

    线性回归原理介绍 线性回归python实现 线性回归sklearn实现 这里使用python实现线性回归,没有使用sklearn等机器学习框架,目的是帮助理解算法的原理. 写了三个例子,分别是单变量的 ...

  9. 基于freeRTOS定时器实现闹钟(定时)任务

    基于freeRTOS定时器实现闹钟(定时)任务 在智能硬件产品中硬件中,闹钟定时任务是基本的需求.一般通过APP设置定时任务,从云端或者是APP直连硬件将闹钟任务保存在硬件flash中,硬件运行时会去 ...

  10. Python3 Tkinter-Radionbutton

    1.创建单选按钮 from tkinter import * root=Tk() Radiobutton(root,text='b1').pack() Radiobutton(root,text='b ...