HDU 1158 Employment Planning

题目地址:点击打开链接

思路:

dp[i][j]表示前i个月最后一个月的总人数为j所花的最小费用

状态移动方程:dp[i][j] = min{dp[i-1][k] + cost[i][j]},其中cost[i][j]是第i月的花费,

1~当k<=j时,第i个月请了人所以cost[i][j] = j*salary + (j-k)*hire
2~当k>j时,第i个月炒了人,所以cost[i][j] = j*salary + (k-j)*fire

写一下我刚开始就存在的2个疑问

1:假设企业这个月需要9个人,为啥雇佣10个人成本最低,企业有时候会留一些不做事的人,因为有时候工资会比雇佣和解雇的成本低

2:企业第i个月j个人时为啥求最小值的时候,要从上一个月的最小人数和最大人数求解,因为上个月人数多成本高,但这个月由于雇佣和解雇的都需要成本的缘故,成本优势会体现出来

AC代码:

#include <iostream>
#include <cstdio>
#include <climits>

using namespace std;

int dp[13][100];

int main()
{
    int n,a[12],i,j,k,max1,max2,temp;
    int hire,salary,fire;
    while(scanf("%d",&n),n)
    {
        max1 = 0;
        scanf("%d%d%d",&hire,&salary,&fire);
        for(i=1; i<=n; i++)
        {
            scanf("%d",&a[i]);
            if(a[i] > max1)
                max1 = a[i];
        }
        for(i=1; i<=max1; i++)
        {
            dp[1][i] = (hire + salary) * i;
        }
        for(i=2; i<=n; i++)
        {
            for(j=a[i]; j<=max1; j++)
            {
                max2 = INT_MAX;
                for(k=a[i-1]; k<=max1; k++)
                {
                    if(k > j)
                        temp = dp[i-1][k] + (k - j) * fire + j * salary;
                    else
                        temp = dp[i-1][k] + (j - k) * hire + j * salary;
                    if(temp < max2)
                        max2 = temp;
                }
                dp[i][j] = max2;
            }
        }
        max2 = INT_MAX;
        for(j=a[n]; j<=max1; j++)
        {
            if(dp[n][j] < max2)
                max2 = dp[n][j];
        }
        printf("%d\n",max2);
    }
    return 0;
}


你可能感兴趣的:(HDU 1158 Employment Planning)