题目:http://acm.hdu.edu.cn/showproblem.php?pid=1158
题意:
公司完成一个项目需要n个月,每个月给出了最少计划人数需求,于是在不同的月份需要hire员工或者fire员工来既满足工程需求又减少公司花费,给定hire一个员工的花费、每个员工的月薪salary、fire一个员工的花费,求计划得到的最少花费。
思路:
第一个月是需要支付hire所有员工的费用,而最后一个月是合同到期,不需要支付fire所有员工的费用,每个月都要付工资;第i个月计划需要最少人数为j=month[i];综合所有月份每个月最多人数需求为needmax,也就是所有人数需求中的最大值;于是每个月的人数计划范围为[j,needmax],第i个月计划k个人(j<=k<=needmax),则前i个月的花费为cost[i][k],那么cost[i][x]=min{cost[i-1][k]+(x-k)*hirecost+x*salary}(j<=k<=needmax),这里的min是比较k变动时得到的大括号里的值,cost[i-1][k]表示前i-1个月计划k个人的最少花费,cost[i][x]表示前i个月计划x个人的最少花费,(x-k)*hirecost表示hire花费,根据人数情况应该还有(k-x)*firecost表示fire花费,x*salary表示月薪;第一个月的花费需要初始化cost[1][k]=(salary+hire)*k,(j<=k<=needmax)。
#include<stdio.h>
int main()
{
int n,i,j,k,needmax,minans,need;
int hire,salary,fire;
int month[13]={0},cost[13][10000]={0};
while(scanf("%d",&n)&&n!=0)
{
scanf("%d %d %d",&hire,&salary,&fire);
needmax=-1;
for(i=1;i<=n;i++)
{
scanf("%d",&month[i]);
if(month[i]>needmax)
needmax=month[i];
}
for(i=month[1];i<=needmax;i++)
cost[1][i]=(salary+hire)*i;
for(i=2;i<=n;i++)
{
for(j=month[i];j<=needmax;j++)
{
minans=1000000000;
for(k=month[i-1];k<=needmax;k++)
{
if(j>k)
need=salary*j + hire*(j-k) + cost[i-1][k];
else
need=salary*j + fire*(k-j) + cost[i-1][k];
if(need < minans)
minans=need;
}
cost[i][j]=minans;
}
}
minans=1000000000;
for(i=month[n];i<=needmax;i++)
{
if(cost[n][i] < minans)
minans=cost[n][i];
}
printf("%d\n",minans);
}
return 0;
}