链接: HDU1158
题目大意是:每个月解雇或雇佣一些员工,每次雇佣或解雇一名员工时,将会有一些额外的成本,要求每个月雇佣或解雇多少工人能让成本最低。题目会告诉每个月最少工人数和雇佣和解雇一个工人的花费。
先求出所有月份中需要的最多的人工数,记作Max。
因为是求最低成本所以每月雇佣的人数p[i]<=Max.
h:雇佣的成本 s:工资 f:解雇的钱
如果p[i]>=p[i-1] 当月花费为: 上个月的花费+h*(p[i]-p[i-1])+s*p[i];
如果p[i]<p[i-1] : 上个月的花费+f*(p[i-1]-p[i])+s*p[i]
dp[i][j]表示第i个月j个人的花费
代码如下:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int main(){
int n,h,s,f,p[12],dp[12][10005],Max;
while(scanf("%d",&n)!=EOF){
if(!n)break;
memset(dp,0,sizeof(dp));
scanf("%d%d%d",&h,&s,&f);
Max=-1;
for(int i=0;i<n;i++){
scanf("%d",&p[i]);
Max=max(p[i],Max);
}
for(int i=p[0];i<=Max;i++){
dp[0][i]=i*s+i*h;
}
for(int i=1;i<n;i++){
for(int j=p[i];j<=Max;j++){
dp[i][j]=1e9+7;
for(int k=p[i-1];k<=Max;k++){
if(k<=j){
dp[i][j]=min(dp[i][j],dp[i-1][k]+h*(j-k)+s*j);
}
else{
dp[i][j]=min(dp[i][j],dp[i-1][k]+f*(k-j)+s*j);
}
}
}
}
int x=1e9+7;
for(int i=p[n-1];i<=Max;i++)
x=min(x,dp[n-1][i]);
printf("%d\n",x);
}
return 0;
}