HDU1158_Employment Planning【DP】

Employment Planning

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 3814    Accepted Submission(s): 1574

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)

题目大意:老板想要决定M个月每个月需要的工人数,已知雇佣一个工人的价格,

工人的月薪,解雇一个工人的价格,又知道M个月每个月至少需要多少个工人。问:

怎样雇佣工人,才能使得满足M个月工人需求的同时,付出最少的钱。

思路:在M个月中求出最大的需求人数Max,那么无论下个月需要多少个工人,最多

雇佣Max个工人也就够了。

状态转移方程:dp[i][j] = min(dp[i-1][k] + cost)(num[i-1] <=k <= Max)

意思是:第i个月雇佣j个人 = 当上个月雇佣k个人时的最小花费 + 雇佣或解雇所需要

的花费这样三重循环遍历得出解雇。第一层代表第i个月,第二层代表第i月雇佣j个人

,第三层代表第i-1月雇佣k个人。最里层循环得出dp[i][j]。最后当第M个月的最小花

费就是将dp[M][i](num[M]<=i<=Max)遍历一遍求得M个月最小花费。

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
//dp[i][j] = min(dp[i-1][k] + cost)(num[i-1] <=k <= Max)
int num[15],dp[15][1100],hire,fire,salary;
int main()
{
    int M,Max,Min,temp;
    while(~scanf("%d",&M) && M)
    {
        scanf("%d%d%d",&hire,&salary,&fire);
        Max = 0;
        for(int i = 1; i <= M; i++)
        {
            scanf("%d",&num[i]);
            if(num[i]>Max)
                Max = num[i];
        }

        for(int i = num[1]; i <= Max; i++)
            dp[1][i] = (hire+salary)*i;
        for(int i = 2; i <= M; i++)
        {
            for(int j = num[i]; j <= Max; j++)
            {
                Min = 0xffffff0;
                for(int k = num[i-1];k <= Max; k++)
                {
                    if(k > j)
                        temp = dp[i-1][k] + fire*(k-j) + salary*j;
                    else
                        temp = dp[i-1][k] + hire*(j-k) + salary*j;
                    if(temp < Min)
                        Min = temp;
                }
                dp[i][j] = Min;
            }
        }
        int ans = 0xffffff0;
        for(int i = num[M]; i<= Max; i++)
            ans = min(ans,dp[M][i]);
        printf("%d\n",ans);

    }

    return 0;
}
时间: 2024-08-30 05:50:04

HDU1158_Employment Planning【DP】的相关文章

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

hdoj 2391 Filthy Rich 【DP】

题目大意:有个二维数组,你从(0,0)出发,最终到(n,m), 在这个二维数组中,每个位置dp[i][j]都有一定量的黄金,你可以拾取,问你最多能失去多少,并且,你的方向有下,右, 斜向下三个方向: 策略:就是每一个都加上它的上方向与左方向的最大值,这样到最后就是最大值.详情见代码 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2391 代码: #include<stdio.h> #include<string.h> int dp[1

HDOJ1176 免费馅饼 【DP】+【经典数塔】

免费馅饼 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 23986    Accepted Submission(s): 8093 Problem Description 都说天上不会掉馅饼,但有一天gameboy正走在回家的小径上,忽然天上掉下大把大把的馅饼.说来gameboy的人品实在是太好了,这馅饼别处都不掉,就掉落在他身旁的1

nyoj 325 zb的生日 【DP】||【DFS】

两种方法: 第一种:将总数一半当做背包,用总数-2*最多能装的数目就是所求: 第二种:深搜: zb的生日 时间限制:3000 ms  |  内存限制:65535 KB 难度:2 描述 今天是阴历七月初五,acm队员zb的生日.zb正在和C小加.never在武汉集训.他想给这两位兄弟买点什么庆祝生日,经过调查,zb发现C小加和never都很喜欢吃西瓜,而且一吃就是一堆的那种,zb立刻下定决心买了一堆西瓜.当他准备把西瓜送给C小加和never的时候,遇到了一个难题,never和C小加不在一块住,只能

HDOJ4540 威威猫系列故事——打地鼠 【DP】

威威猫系列故事--打地鼠 Time Limit: 300/100 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Total Submission(s): 1445    Accepted Submission(s): 713 Problem Description 威威猫最近不务正业,每天沉迷于游戏"打地鼠". 每当朋友们劝他别太着迷游戏,应该好好工作的时候,他总是说,我是威威猫,猫打老鼠就是我的工作! 无话

NYOJ16 矩形嵌套 【DP】

矩形嵌套 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描述 有n个矩形,每个矩形可以用a,b来描述,表示长和宽.矩形X(a,b)可以嵌套在矩形Y(c,d)中当且仅当a<c,b<d或者b<c,a<d(相当于旋转X90度).例如(1,5)可以嵌套在(6,2)内,但不能嵌套在(3,4)中.你的任务是选出尽可能多的矩形排成一行,使得除最后一个外,每一个矩形都可以嵌套在下一个矩形内. 输入 第一行是一个正正数N(0<N<10),表示测试数据组数, 每组

hdoj 2046 骨牌铺方格 【DP】+【斐波那契】

dp果然不是好学的... 第n个,即2*n时,可由第n-1个的竖直排列再加一个,和第n-2个中横着排两个 所以f(n) = 1×f(n-1) + 1×f(n-2): 骨牌铺方格 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 28412    Accepted Submission(s): 13771 Problem Descripti

【题解】【数组】【DP】【Codility】MaxSliceSum &amp; MaxDoubleSliceSum

MaxSliceSum 5 -7 3 5 -2 4 -1 这个数组的最大子串是3 5 -2 4 Complexity: expected worst-case time complexity is O(N); expected worst-case space complexity is O(1), beyond input storage (not counting the storage required for input arguments). 思路 O(n) 的解法的关键,是把原来求最

[HDOJ - 5282] Senior&#39;s String 【DP】

题目链接:BZOJ - 5282 题目分析 LCS 就是用经典的 O(n^2) DP 解决,f[i][j] 表示 x 串前 i 个字符与 y 串前 j 个字符的 LCS 长度. f[i][j] = max(f[i - 1][j], f[i][j - 1]); if (x[i] == y[j]) f[i][j] = max(f[i][j], f[i - 1][j - 1] + 1); 然后再设置一个状态 g[i][j], 表示 x 串的前 i 个字符中,有多少个长为 f[i][j] 的子序列同时也