HDU_1158 Employment Planning(DP)

  又是一道纠结的dp题,做dp快做的崩溃了。。。

 状态表示:    

 Dp[i][j]为前i个月的留j个人的最优解;Num[i]<=j<=Max{Num[i]};
                j
>Max{Num[i]}之后无意义,无谓的浪费 记Max_n=Max{Num[i]};
    Dp[i
-1]中的每一项都可能影响到Dp[i],即使Num[i-1]<<Num[i]
    所以利用Dp[i
-1]中的所有项去求Dp[i];
    对于Num[i]
<=k<=Max_n,   

 当k<j时, 招聘;  当k>j时, 解雇  然后求出最小值
    Dp[i][j]
=min{Dp[i-1][k…Max_n]+(招聘,解雇,工资);   


代码:

#include <iostream>
#include
<cstdio>
#include
<cstring>

using namespace std;

const int N = 10000;
const int inf = 0xfffffff;

int mon[13];
int dp[13][N];

int main()
{
//freopen("data.in", "r", stdin);

int m, i, j, k;
while(scanf("%d", &m), m)
{
int hire, fire, salary, max, min, cost;

memset(dp,
0, sizeof(dp));
memset(mon,
0, sizeof(mon));

scanf(
"%d%d%d", &hire, &salary, &fire);
max
= -inf;

for(i = 1; i <= m; i++)
{
scanf(
"%d", mon + i);
max
= max > mon[i] ? max : mon[i];
}

for(i = mon[1]; i <= max; i++)
dp[
1][i] = (hire+salary) * i;

for(i = 2; i <= m; i++)
{
for(j = mon[i]; j <= max; j++)
{
min
= inf;
for(k = mon[i-1]; k <= max; k++)
{
if(k <= j)
cost
= (j-k)*hire + j*salary + dp[i-1][k];
else
cost
= (k-j)*fire + j*salary + dp[i-1][k];
if(min > cost)
min
= cost;
}
//printf("%d\n", min);
dp[i][j] = min;
}
}

min
= inf;
for(i = mon[m]; i <= max; i++)
if(min > dp[m][i])
min
= dp[m][i];
printf(
"%d\n", min);
}
return 0;
}


posted @ 2011-09-05 21:14  AC_Von  阅读(171)  评论(0编辑  收藏  举报