状态表示: Dp[i][j]为前i个月的留j个人的最优解;Num[i]<=j<=Max{Num[i]};
j>Max{Num[i]}之后无意义,无谓的浪费 记Max_n=Max{Num[i]};
Dp[i-1]中的每一项都可能影响到Dp[i],即使Num[i-1]<<Num[i]
所以利用Dp[i-1]中的所有项去求Dp[i];
对于Num[i]<=k<=Max_n, 当k<j时, 招聘;
当k>j时, 解雇 然后求出最小值
j>Max{Num[i]}之后无意义,无谓的浪费 记Max_n=Max{Num[i]};
Dp[i-1]中的每一项都可能影响到Dp[i],即使Num[i-1]<<Num[i]
所以利用Dp[i-1]中的所有项去求Dp[i];
对于Num[i]<=k<=Max_n, 当k<j时, 招聘;
当k>j时, 解雇 然后求出最小值
Dp[i][j]=min{Dp[i-1][k…Max_n]+(招聘,解雇,工资);
#include <iostream>
using namespace std;
const int N = 13;
const int M = 1000000;
int dp[N][M];
int main()
{
int n;
while(cin >> n, n)
{
int h, s, f;
cin >> h >> s >> f;
int need[N];
for(int i = 0; i < n; i++)
cin >> need[i];
int max = 0;
for(int i = 0; i < n; i++)
if(need[i] > max)
max = need[i];
memset(dp, 0, sizeof(dp));
for(int i = need[0]; i <= max; i++)
dp[0][i] = i * (h + s);
for(int i = 1; i < n; i++)
{
for(int j = need[i]; j <= max; j++)
{
int min = 99999999;
for(int k = need[i-1]; k <= max; k++)
{
int temp = 0;
if(j >= k) //需要雇佣
temp = (j - k) * h + j * s + dp[i-1] [k];
else
temp = (k - j) * f + j * s + dp[i-1] [k];
if(temp < min)
min = temp;
}
dp[i][j] = min;
}
}
int min = 99999999;
for(int j = need[n-1]; j <= max; j++)
if(dp[n-1][j] < min)
min = dp[n-1][j];
cout << min << endl;
}
return 0;
}