HDU 1158 Employment Planning (DP)

Problem Description

A project manager wants to determine the number of the workers needed in every month. He does know the minimal number of the workers needed in each month. When he hires or fires a worker, there will be some extra cost. Once a worker is hired, he will get the
salary even if he is not working. The manager knows the costs of hiring a worker, firing a worker, and the salary of a worker. Then the manager will confront such a problem: how many workers he will hire or fire each month in order to keep the lowest total
cost of the project.

Input

The input may contain several data sets. Each data set contains three lines. First line contains the months of the project planed to use which is no more than 12. The second line contains the cost of hiring a worker, the amount of the salary, the cost of firing
a worker. The third line contains several numbers, which represent the minimal number of the workers needed each month. The input is terminated by line containing a single ‘0‘.

Output

The output contains one line. The minimal total cost of the project.

Sample Input

3
4 5 6
10 9 11
0

Sample Output

199

Source

Asia 1997, Shanghai (Mainland China)

雇佣人:有三项费用:雇佣费(h),工资(w),解雇费(f)

给你n个月需要的人数,求最小的支出费用。。。。。

dp[i][j]:第i天雇佣j个人的费用,确定最大的天数maxn

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<limits.h>
using namespace std;
int h,w,f;
int a[100000];
;int dp[15][100000];
int main()
{
    int n,maxn,minn;
    while(~scanf("%d",&n)&&n)
    {
        scanf("%d%d%d",&h,&w,&f);
        int maxn=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            if(a[i]>maxn)
                maxn=a[i];
        }
        for(int j=a[1];j<=maxn;j++)//第一天的状态可以确定
            dp[1][j]=(h+w)*j;
        for(int i=2;i<=n;i++)
        {
            for(int j=a[i];j<=maxn;j++)//j天雇佣的人数
            {
                minn=INT_MAX;
                for(int k=a[i-1];k<=maxn;k++)//j的前一天雇佣人数
                {
                    if(j>=k)
                        dp[i][j]=(j-k)*h+j*w+dp[i-1][k];
                    else
                        dp[i][j]=(k-j)*f+j*w+dp[i-1][k];
                    if(dp[i][j]<minn)
                        minn=dp[i][j];
                }
                dp[i][j]=minn;//取最小值
            }
        }
        minn=INT_MAX;
        for(int i=a[n];i<=maxn;i++)//不确定最后一天雇佣了几个人,所以要遍历
        {
            if(dp[n][i]<minn)
                minn=dp[n][i];
        }
        printf("%d\n",minn);
    }
    return 0;
}

HDU 1158 Employment Planning (DP)

时间: 2024-08-02 18:41:02

HDU 1158 Employment Planning (DP)的相关文章

hdu 1158 Employment Planning(DP)

题意: 有一个工程需要N个月才能完成.(n<=12) 给出雇佣一个工人的费用.每个工人每个月的工资.解雇一个工人的费用. 然后给出N个月所需的最少工人人数. 问完成这个项目最少需要花多少钱. 思路: 将(i,num):[第i个月拥有num个工人 ]看成一个状态.那么就想到用DP. 看代码 代码: struct node{ int minNum, maxNum; } month[15]; int n; int hire,salary,fire; int dp[15][505]; int main(

HDU 1158 Employment Planning【DP】

题意:给出n个月,雇佣一个人所需的钱hire,一个人工作一个月所需要的钱salary,解雇一个人所需要的钱fire,再给出这n个月每月1至少有num[i]个人完成工作,问完成整个工作所花费的最少的钱是多少. 用dp[i][j]表示在第i个月雇佣j个人所需要的最少花费 先考虑只解雇人和聘请人的情况 1 for(j=num[i];j<=sum;j++) 2 { 3 if(j>num[i-1])//说明雇佣了人 4 dp[i][j]=dp[i-1][num[i-1]]+j*salary+(j-num

HDU 1158 Employment Planning

题意:有一公司要工作n个月每个月需要至少p[i]个人工作,每个人的工资固定位m, 每雇佣一个人要花费h,每炒掉一个人要花费f.求完成n个月工作,公司最小的花费. 思路: Dp[i][j]为前i个月的留j个人的最优解;p[i]<=j<=Max{p[i]}; j>Max{p[i]}之后无意义,无谓的浪费 记Max_n=Max{p[i]}; Dp[i-1]中的每一项都可能影响到Dp[i],即使p[i-1]<<p[i] 所以利用Dp[i-1]中的所有项去求Dp[i]; 对于p[i]&

hdu1158 Employment Planning(dp)

题目传送门 Employment Planning Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 6242    Accepted Submission(s): 2710 Problem Description A project manager wants to determine the number of the workers

Hdu 1158 Employment Planning(DP)

Problem地址:http://acm.hdu.edu.cn/showproblem.php?pid=1158 一道dp题,或许是我对dp的理解的还不够,看了题解才做出来,要加油了. 只能先上代码了. #include <iostream> #include <cstring> #include <cstdio> using namespace std; const int MAXN = 100 + 28; int dp[15][MAXN]; int workers[

HDU 4745 Two Rabbits(DP)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4745 题意:n个数排成一个环.两个人AB初始时各自选定一个位置.每一轮A在顺时针方向选择一个位置,B在逆时针选择一个位置,且这两个人所选位置的数字相等,然后格子跳到新选的位置上.问最多进行多少轮?有一个限制为每次跳跃不能跨过以前自己曾经选过的格子. 思路:主要是分析问题的本质.其实就是求最长回文子列.f[i][j]为[i,j]的最长回文子列,则答案为max(f[1][i],f[i+1][n]). i

HDU 4833 Best Financing (DP)

Best Financing Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 29    Accepted Submission(s): 3 Problem Description 小A想通过合理投资银行理财产品达到收益最大化.已知小A在未来一段时间中的收入情况,描述为两个长度为n的整数数组dates和earnings,表示在第dat

HDU 1260:Tickets(DP)

Tickets Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 923    Accepted Submission(s): 467 Problem Description Jesus, what a great movie! Thousands of people are rushing to the cinema. However,

hdu 1421 搬寝室 (dp)

思路分析: dp[i][j] 表示选取到第 i 个   组成了 j 对的最优答案. 当然排序之后 选取相邻两个是更优的. if(i==j*2) dp[i][j] = dp[i-2][j-1] + w[i]-w[i-2]^2.. else if( i> j*2 ) dp[i][j] = min (dp[i-2][j-1] + ...^2   ,    dp[i-1][j]).... #include <cstdio> #include <iostream> #include &