HDU 1158 传送门:Employment Planning
题目大意:
一个项目经理准备招一部分工人做事,每个月所需要的工人人数不一样,
经理可以看情况hires or fires a worker,雇人或解雇都需要钱,雇的人不干活也需要发工资,
要求怎样安排才能使得完成整个工作花费最少?
分析 :
以第i个月结束时,现有j个人的最小花费dp[i][j]为状态量,对人数进行举,
状态转移方程 : dp[i][j] = min(dp[i][j] , dp[i][k] + cost ,( num[i-1]< k < max))
Code:
#include"stdio.h"
#define MAX_WORKER 0x9999
int months;
int hireCost, salary, fireCost;
int minMonthWorker[13],maxWorker; //每个月份雇佣的最小人数
int cost[13][MAX_WORKER]; // 月份 & 工人数
void input();
void initCostArray();
void calculateCostArray();
void out();
int main(){
while(~scanf("%d",&months),months)
{
input();
out();
}
return 0;
}
void input(){
scanf("%d%d%d",&hireCost,&salary,&fireCost);
maxWorker = 0;
for(int i = 1;i <= months;i ++){
scanf("%d",&minMonthWorker[i]);
if(minMonthWorker[i] > maxWorker) {
maxWorker = minMonthWorker[i];
}
}
initCostArray();
}
void initCostArray(){
for(int i = minMonthWorker[1];i <= maxWorker;i ++){
cost[1][i] = hireCost*i + salary*i;
}
calculateCostArray();
}
void calculateCostArray(){
for(int i = 2; i <= months; i ++){
for(int j = minMonthWorker[i]; j <= maxWorker; j ++){
int costMin = 0x999999;
int temp;
for(int k = minMonthWorker[i-1]; k <= maxWorker ;k ++){
if(k > j){
temp = cost[i-1][k] + fireCost*(k-j) + salary*j;
}else{
temp = cost[i-1][k] + hireCost*(j-k) + salary*j;
}
if(temp < costMin)
costMin = temp;
}
cost[i][j] = costMin;
}
}
}
void out(){
int tempMin = 0x999999;
for(int i = minMonthWorker[months] ; i <= maxWorker; i ++)
if(cost[months][i] < tempMin)
tempMin = cost[months][i];
printf("%d\n",tempMin);
}