P3049 [USACO12MAR] Landscaping S

P3049 [USACO12MAR] Landscaping S

文章目录

  • P3049 [USACO12MAR] Landscaping S
    • 题目描述
    • 输入格式
    • 输出格式
    • 样例 #1
      • 样例输入 #1
      • 样例输出 #1
    • 提示
    • 思路
    • code

[P3049 USACO12MAR] Landscaping S - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

题目描述

Farmer John 打算修建一座花园,他需要移动不少泥土。

花园由 N N N 个花坛组成( 1 ≤ N ≤ 100 1 \leq N \leq 100 1N100),其中花坛 i i i 包含 A i A_i Ai 单位的泥土。FJ 希望花坛 i i i 包含 B i B_i Bi 单位的泥土,保证 0 ≤ A i , B i ≤ 10 0 \leq A_i,B_i \leq 10 0Ai,Bi10

为了达到这个目标,他可以做这几件事情:

  • 购买一单位的泥土,放在指定的花坛中,费用为 X X X
  • 从任意一个花坛中移走一单位泥土,费用为 Y Y Y
  • 从花坛 i i i 运送一单位泥土到花坛 j j j,费用为 Z ∣ i − j ∣ Z|i-j| Zij

请你帮 FJ 计算移动泥土的最小开销。

输入格式

第一行四个整数 N , X , Y , Z N,X,Y,Z N,X,Y,Z 0 ≤ X , Y , Z ≤ 1000 0 \leq X,Y,Z \leq 1000 0X,Y,Z1000)。

接下来 N N N 行,第 i i i 行两个整数 A i , B i A_i,B_i Ai,Bi

输出格式

输出移动泥土的最小开销。

样例 #1

样例输入 #1

4 100 200 1 
1 4 
2 3 
3 2 
4 0

样例输出 #1

210

提示

按下面的方案,最小花费为 210 210 210,可以证明不存在开销更小的方案。

  • 移除 4 4 4 号花坛的一单位泥土,花费 200 200 200
  • 4 4 4 号花坛的三单位泥土移到 1 1 1 号花坛,花费 3 × 3 = 9 3 \times 3=9 3×3=9
  • 3 3 3 号花坛的一单位泥土移到 2 2 2 号花坛,花费 1 × 1 = 1 1 \times 1=1 1×1=1

思路

把数组按照如下方式离散化一下

1 2 4 3

1 2 2 3 3 3 3 4 4 4

设 $dp_{i , j} $ 表示前 i i i j j j 个满足条件的最小代价


d p i , j = m i n ( d p i − 1 , j + y , d p i , j − 1 + x , d p i − 1 , j − 1 + z ∗ a b s ( a i − b j ) ) dp_{i , j} = min(dp_{i - 1 , j} + y , dp_{i , j - 1} + x , dp{i - 1 , j - 1} + z * abs (a_i - b_j)) dpi,j=min(dpi1,j+y,dpi,j1+x,dpi1,j1+zabs(aibj))

code

#include 
#define LL long long 
#define fu(x , y , z) for(int x = y ; x <= z ; x ++)
using namespace std;
const int N = 2005;
int n , x , y , z , l1 , l2;
LL a[N] , b[N] , dp[N][N];
int main () {
    int r1 , r2;
    scanf ("%d%d%d%d" , &n , &x , &y , &z);
    fu (i , 1 , n) {
        scanf ("%d%d" , &r1 , &r2);
        fu (j , l1 + 1 , l1 + r1) a[j] = i;
        fu (j , l2 + 1 , l2 + r2) b[j] = i;
        l1 += r1 , l2 += r2;
    }
    fu (i , 1 , l1) dp[i][0] = i * y;
    fu (i , 1 , l2) dp[0][i] = i * x;
    fu (i , 1 , l1)
        fu (j , 1 , l2)
            dp[i][j] = min (dp[i - 1][j] + y , min (dp[i][j - 1] + x , dp[i - 1][j - 1] + z * abs (a[i] - b[j])));
    printf ("%lld" , dp[l1][l2]);
    return 0;
}

你可能感兴趣的:(USACO,数据结构,dp,算法,动态规划,图论)