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 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)

Recommend

Ignatius   |   We have carefully selected several similar problems for you:  1227 1074 1080 1024 1078

题意:给出n个月,雇佣价钱,工资和辞退价钱;然后给出每个月所需的人数,

求最小花费

题解:定义dp[i][j]为以i月份结尾,j个人数的花费最小值

则dp[i][j]=min{dp[i-1][k]+cost[i][j]};

其中当k<=j时,cost[i][j]=j*salary+(j-k)*hire;

k>j时,cost[i][j]=j*salary+(k-j)*fire;

边界就是 for(int i=people[1];i<=maxn;i++)
        dp[1][i]=i*salary+i*hire;

#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define mod 1000000007
#define INF 0x3f3f3f3f
int n;
int people[13];
int dp[13][10000];
int hire,salary,fire;
int main()
{
    while(cin>>n)
    {
        if(n==0) break;
        cin>>hire>>salary>>fire;
        int maxn=0;
        for(int i=1;i<=n;i++)
        {
            cin>>people[i];
            maxn=max(maxn,people[i]);
        }
        memset(dp,INF,sizeof(dp));
        for(int i=people[1];i<=maxn;i++)
        dp[1][i]=i*salary+i*hire;
      for(int i=2;i<=n;i++)
      {
          for(int j=people[i];j<=maxn;j++)
          {
              for(int k=people[i-1];k<=maxn;k++)
              {
                  if(k<=j)
                  dp[i][j]=min(dp[i][j],dp[i-1][k]+j*salary+(j-k)*hire);
                  else
                  dp[i][j]=min(dp[i][j],dp[i-1][k]+j*salary+(k-j)*fire);
              }
          }
      }
      int minn=INF;
      for(int i=people[n];i<=maxn;i++)
      {
          minn=min(minn,dp[n][i]);
      }
      cout<<minn<<endl;
    }
    return 0;
}

原文地址:https://www.cnblogs.com/zhgyki/p/9595420.html

时间: 2024-11-05 00:30:13

hdu1158 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)

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 work

HDU1158 Employment Planning 基础DP

Employment Planning 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 ext

hdu 5623 KK&#39;s Number(dp)

问题描述 我们可爱的KK有一个有趣的数学游戏:这个游戏需要两个人,有N\left(1\leq N\leq 5*{10}^{4} \right)N(1≤N≤5∗10?4??)个数,每次KK都会先拿数.每次可以拿任意多个数,直到NN个数被拿完.每次获得的得分为取的数中的最小值,KK和对手的策略都是尽可能使得自己的得分减去对手的得分更大.在这样的情况下,最终KK的得分减去对手的得分会是多少? 输入描述 第一行一个数T\left( 1\leq T\leq 10\right)T(1≤T≤10),表示数据组

Ural 1353 Milliard Vasya&#39;s Function(DP)

题目地址:Ural 1353 定义dp[i][j],表示当前位数为i位时,各位数和为j的个数. 对于第i位数来说,总可以看成在前i-1位后面加上一个0~9,所以状态转移方程就很容易出来了: dp[i][j]=dp[i][j]+dp[i][j-1]+dp[i][j-2]+.......+dp[i][j-9]: 最后统计即可. 代码如下: #include <iostream> #include <cstdio> #include <string> #include <

City Planning (图论) (无向图)

City Planning Problem Description Recently Bob received a job. It's to reform the city's transport system. Since the city has so many villages, and the transportation network is so large that the government want to reduce the roads number. The govern

HDU 4908 (杭电 BC #3 1002题)BestCoder Sequence(DP)

题目地址:HDU 4908 这个题是从m开始,分别往前DP和往后DP,如果比m大,就比前面+1,反之-1.这样的话,为0的点就可以与m这个数匹配成一个子串,然后左边和右边的相反数的也可以互相匹配成一个子串,然后互相的乘积最后再加上就行了.因为加入最终两边的互相匹配了,那就说明左右两边一定是偶数个,加上m就一定是奇数个,这奇数个的问题就不用担心了. 代码如下: #include <iostream> #include <stdio.h> #include <string.h&g

Sicily 1146:Lenny&#39;s Lucky Lotto(dp)

题意:给出N,M,问有多少个长度为N的整数序列,满足所有数都在[1,M]内,并且每一个数至少是前一个数的两倍.例如给出N=4, M=10, 则有4个长度为4的整数序列满足条件: [1, 2, 4, 8], [1, 2, 4, 9], [1, 2, 4, 10], [1, 2, 5, 10] 分析:可用动态规划解题,假设dp[i][j],代表满足以整数i为尾数,长度为j的序列的个数(其中每一个数至少是前一个数的两倍).那么对于整数i,dp[i][j] 等于所有dp[k][j-1]的和,其中k满足:

UVA542 - France &#39;98(dp)

UVA542 - France '98(dp) 题目链接 题目大意:之前题目意思还以为看懂了,其实没看明白,它已经把各个选手分在各自所在的区域里面,这就意味着第一次的PK的分组已经确定,而且冠军必须是从两个左右分区出来的胜利者才有机会pk冠军. 解题思路:那么从1-16这个大的区间内诞生出来的冠军可能是来自左边,也可能是右边,然后再左边右边的子区间递归找出冠军.f[i][l][r]表示l-r这个区间的胜利者是i的概率,那么假设i在区间的最左边,f[i][l][r] = Sum(f[i][l][m