hdu 1158 Employment Planning

来源:互联网 发布:ubuntu新建文件夹 编辑:程序博客网 时间:2024/05/21 09:05

hdu 1158 Employment Planning

题目大意: 一个公司在n个月里需要  a[1] , a[2]~~ a[n] 个人 , 招一个人,一个人每个月的工资和解雇一个人分别要花费 hire ,salary , fire的金钱,求n个月里花费的最小金额。

解题思路:dp

要使得 n 个月的时候钱最小,那么 n-1 的钱也是最小的。

如果n 个月需要的人数大于 n-1 个月需要的人数,则  dp[n][k] = dp[n-1][k] + (j-k)*hire + j*salary ;

如果n 个月需要的人数 小于 n-1 个月需要的人数 ,则 dp[n][k] = dp[n-1][k]+(k-j)*fire + j*salary ;

 感觉代码的大意就是,因为 不知道第一个月是 招多小人好,所以 要每一个都判一遍 , 然后再判第二个月招多小人合适 于是就有了 三个 for  循环。

最后因为不知道 招多小人最小,于是再在 month[ n ] 到 maxn 中找最小。

代码:

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#define inf 0x7ffffffusing namespace std;int n,dp[13][1110],month[1110];int hire,salary,fire;int maxn,minn,sum;int main(){    int i,j,k,temp;    while(scanf("%d",&n)!=EOF&&n!=0)    {        memset(dp,0,sizeof(dp));        maxn=0;        scanf("%d%d%d",&hire,&salary,&fire);        for(i=1;i<=n;i++)        {            scanf("%d",&month[i]);            maxn=max(maxn,month[i]);        }        if(maxn==0)        {            printf("0\n");            continue;        }        for(i=month[1];i<=maxn;i++)        {            dp[1][i]=(hire+salary)*i;        }        for(i=2;i<=n;i++)        {            for(j=month[i];j<=maxn;j++)            {                minn=inf;                for(k=month[i-1];k<=maxn;k++)                {                    if(j>=k)                    {                        temp=dp[i-1][k]+(j-k)*hire+j*salary;                    }                    else                    {                        temp=dp[i-1][k]+(k-j)*fire+j*salary;                    }                    minn=min(minn,temp);                }                dp[i][j]=minn;            }        }        sum=inf;        for(j=month[n];j<=maxn;j++)        {            if(sum>dp[n][j])                sum=dp[n][j];        }        printf("%d\n",sum);    }    return 0;}

0 0
原创粉丝点击