题目大意:
一个公司知道他每个月需要多少员工。
又给出每个员工的工资。
每次招聘或者解雇一个人的时候都会给出额外的钱。
思路分析:
dp [i][j] 表示第i 个月的时候手上有 j 名员工的最优解。
状态转移要从上一个月的状态转移过来。
但是要求到的是最大值。
dp[i] [j] = min(dp[i][j] , dp[i-1][ a[i-1] --- Max ] + 额外费用+ 工资)...
这道题目的数据范围不是很清晰。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <set>
#include <vector>
#define maxn 1005
using namespace std;
int a[maxn];
int hire,sala,fire;
int dp[20][maxn];
int main()
{
int n;
while(scanf("%d",&n)!=EOF && n)
{
int m=0;
scanf("%d%d%d",&hire,&sala,&fire);
for(int i=1;i<=n;i++)scanf("%d",&a[i]),m=max(m,a[i]);
memset(dp,0x3f,sizeof dp);
for(int i=0;i<=m;i++)
dp[1][i]=hire*i+sala*i;
for(int i=2;i<=n;i++)
{
for(int s=a[i];s<=m;s++)
{
for(int j=a[i-1];j<=m;j++)
{
if(j<s)dp[i][s]=min(dp[i][s],dp[i-1][j]+(s-j)*hire+sala*s);
else if(j==s)dp[i][s]=min(dp[i][s],dp[i-1][j]+sala*s);
else dp[i][s]=min(dp[i][s],dp[i-1][j]+(j-s)*fire+sala*s);
}
}
}
int ans=0x3f3f3f3f;
for(int i=a[n];i<=m;i++)
ans=min(ans,dp[n][i]);
printf("%d\n",ans);
}
return 0;
}