dp, 注意判断不可达的点。
dp[i][j] 表示第i个月雇佣j个员工的最小cost,分别可以又上一个月裁员和雇人得到,选择最优的,复杂度O(n^3).
/*
PROG: Employment Planning
LANG: C++11
*/
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdlib>
#include <climits>
#include <ctype.h>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <deque>
#include <set>
#include <map>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <time.h>
using namespace std;
#define mst(a,b) memset(a,b,sizeof(a))
typedef long long ll;
const int N = 10001;
const ll MOD = 1000000007;
const int INF = 0x7fffffff;
int a[N];
int dp[13][N];
int main()
{
int m, hire, fire, salary, i, j, k;
int s, n;
while(scanf("%d%d%d%d", &m, &hire, &salary, &fire) != EOF ){
if(m == 0) break;
s = INF; n = 0;
for(i = 1; i <= m; i++){
scanf("%d", &a[i]);
s = min(s, a[i]);
n = max(n, a[i]);
}
for(i = 0; i < 13; i++)
for(j = 0; j < N; j++)
dp[i][j] = INF;
//first month
for(j = s; j <= n; j++){
if(j >= a[1])
dp[1][j] = (hire+salary)*j;
else
dp[1][j] = -1;
}
int extra = 0;
for(i = 2; i <= m; i++){
for(j= s; j <= n ;j++){
if(j < a[i]){
dp[i][j] = -1;
}
else{
for(k = s; k <= n; k++){
if(dp[i-1][k] != -1 && dp[i-1][k] != INF){
if(j >= k){
extra = hire*(j-k)+j*salary;
dp[i][j] = min(dp[i-1][k] + extra, dp[i][j]);
}
else{
extra = fire*(k-j)+ j*salary;
dp[i][j] = min(dp[i][j], dp[i-1][k] + extra);
}
}
}
}
}
}
int ans = INF;
for(i = a[m]; i <= n; i++){
ans = min(ans, dp[m][i]);
}
cout << ans << endl;
}
return 0;
}