HDU 1158 Employment Planning

来源:互联网 发布:梦幻西游手游 for mac 编辑:程序博客网 时间:2024/05/18 02:54

题目地址:点击打开链接

思路:

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;}


0 0
原创粉丝点击