HDU OJ Employment Planning
Employment Planning
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 27 Accepted Submission(s) : 14
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
A project manager wants to determine the number of the workers needed in every month. He does know the minimal number of the workers needed in each month. When he hires or fires a worker, there will be some extra cost. Once a worker is hired, he will get the salary even if he is not working. The manager knows the costs of hiring a worker, firing a worker, and the salary of a worker. Then the manager will confront such a problem: how many workers he will hire or fire each month in order to keep the lowest total cost of the project.
Input
The input may contain several data sets. Each data set contains three lines. First line contains the months of the project planed to use which is no more than 12. The second line contains the cost of hiring a worker, the amount of the salary, the cost of firing a worker. The third line contains several numbers, which represent the minimal number of the workers needed each month. The input is terminated by line containing a single '0'.
Output
The output contains one line. The minimal total cost of the project.
Sample Input
3 4 5 6 10 9 11 0
Sample Output
199
题目大意:一个项目经理准备招一部分工人做事,每个月所需要的工人人数不一样,经理可以看情况hires or fires a worker,雇人或解雇都需要钱,雇的人不干活也需要发工资,要求怎样安排才能使得完成整个工作花费最少
算法分析:简单dp,以第i个月结束时,现有j个人的最小花费dp[i][j]为状态量,对人数进行枚举,状态转移方程为dp[i][j] = MAX(dp[i-1][k] + cost, g[i-1] <= k <= maxN),其中cost为从状态dp[i-1][k]转移到dp[i][j]所需额外花费,g[i]表示第i个月所需最少的工人数,maxN表示所有月所需最大的工人数
代码如下:
#include<stdio.h>
#include<string.h>
#define NN 15
#define INF 0xfffffff
int n, hire, sala, fire, maxN;
int g[NN];
int dp[NN][1000];
void solve()
{
int i, j, k, min, tmp;
for (i = g[1]; i <= maxN; i++)
dp[1][i] = (hire + sala) * i;
for (i = 2; i <= n; i++){
for (j = g[i]; j <= maxN; j++){
min = INF;
for (k = g[i - 1]; k <= maxN; k++){
if (k > j){
tmp = dp[i - 1][k] + fire * (k - j) + sala * j;
}else
tmp = dp[i - 1][k] + hire * (j - k) + sala * j;
if (tmp < min)
min = tmp;
}
dp[i][j] = min;
}
}
min = INF;
for (i = g[n]; i <= maxN; i++)
if (dp[n][i] < min)
min = dp[n][i];
printf("%d\n", min);
}
int main()
{
int i;
while (scanf("%d", &n) != EOF){
if (n == 0) break;
scanf("%d%d%d", &hire, &sala, &fire);
maxN = 0;
for (i = 1; i <= n; i++)
{
scanf("%d", &g[i]);
if (g[i] > maxN)
maxN = g[i];
}
solve();
}
return 0;
}