[BZOJ1742&&1694&&3074] [Usaco2005 nov]Grazing on the Run 边跑边吃草

题目描述

Description

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

Input

  • 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).

Output

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

Sample Input

4 10
1
9
11
19

Sample Output

44

题目分析

区间DP
f[i][j][k]表示 吃完了区间i~j的草 并且此时在区间左/右端点
吃完了区间i~j的草 并且此时在区间左端点的情况 可以是吃完了(i+1)~j的草 并且在区间左端点 从i+1走到i 也可以是 可以是吃完了(i+1)~j的草 并且在区间右端点 再从j走回到i
右端点同理
尝试了一发记忆化搜索

#include <cstdio>
#include <cstring>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
int n,p;
int a[1010];
int f[1010][1010][3];
int dfs(int l,int r,int col)
{
    if(f[l][r][col]!=0x3f3f3f3f) return f[l][r][col];
    if(!col) f[l][r][col]=min(dfs(l+1,r,0)+(n-r+l)*(a[l+1]-a[l]),dfs(l+1,r,1)+(n-r+l)*(a[r]-a[l]));
    else f[l][r][col]=min(dfs(l,r-1,1)+(n-r+l)*(a[r]-a[r-1]),dfs(l,r-1,0)+(n-r+l)*(a[r]-a[l]));
    return f[l][r][col]; 
}
int main()
{
    scanf("%d%d",&n,&p);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    sort(a+1,a+n+1);
    memset(f,0x3f,sizeof f);
    for(int i=1;i<=n;i++)
        f[i][i][0]=f[i][i][1]=n*abs(a[i]-p);
    printf("%d",min(dfs(1,n,0),dfs(1,n,1)));
}

发表评论

邮箱地址不会被公开。 必填项已用*标注