hdu1158 Employment Planning

http://acm.hdu.edu.cn/showproblem.php?pid=1158

题目大意:一个项目经理准备招一部分工人做事,每个月所需要的工人人数不一样,经理可以看情况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 ;
}

 

你可能感兴趣的:(HDU)