Farmer John 打算修建一座花园,他需要移动不少泥土。
花园由 N N N 个花坛组成( 1 ≤ N ≤ 100 1 \leq N \leq 100 1≤N≤100),其中花坛 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 0≤Ai,Bi≤10。
为了达到这个目标,他可以做这几件事情:
请你帮 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 0≤X,Y,Z≤1000)。
接下来 N N N 行,第 i i i 行两个整数 A i , B i A_i,B_i Ai,Bi。
输出移动泥土的最小开销。
4 100 200 1
1 4
2 3
3 2
4 0
210
按下面的方案,最小花费为 210 210 210,可以证明不存在开销更小的方案。
把数组按照如下方式离散化一下
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(dpi−1,j+y,dpi,j−1+x,dpi−1,j−1+z∗abs(ai−bj))
#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;
}