题目链接:

acm.hdu.edu.cn/showproblem.php?pid=1158

Employment Planning

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 6020    Accepted Submission(s): 2609

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
 
 
题意:
一家公式完成一个项目,需要n个月的时间,每个月至少雇佣a1...an个工人,解雇工人和雇佣工人都需要一定的费用,每个月还要给雇来的工人工资,问你最少的花费是多少(不用输出方案,只有输出最优解)
分析:
解雇和雇佣工人都需要一定的费用,现在就是要看每个月怎么对工人进行解雇和雇佣的操作可以使得花费最少,每个月雇佣的工人可以>=这个月必须雇佣的工人数目,具体拿样例分析
3
4 5 6
10 9 11
代表3个月份,雇佣工人耗费4,一个雇佣的工人每月工资5,解雇工人耗费6
第一个月至少雇佣10个人,第二个月至少雇佣9个人,第三个月至少雇佣11个人
做法:
该3个月份中最大工人数目为11,最小工人数目为9
第一个月我们可以雇佣10个工人,或者11个工人
第二个月我们需要的工人底线是9个,如果该月雇佣9个(需要解雇x人,x由上一个月雇佣人数决定(上一个月人数减去9),如果该月雇佣10个人(需要解雇人数x,也由上一个月雇佣人数决定),如果该月雇佣11个人,那么现在我们可能还需要继续的雇佣工人,
第三个月也依次类推,
这样不同的雇佣策略导致我们的花费肯定不同,在这些方案在花费中找到最小的即可
 
dp的关键在于明白:前面一个月雇佣多少个人使得这个月的花费最小
 dp[i][j] :代表在第i个月的时候,雇佣J个人的总费用(雇佣费+工资)
dp[i][j]=dp[i-1][k](前面一个月雇佣k个人,可以使得前面的i个月(包括i)的花费最小)+这个月的费用
          =dp[i-1][k]+abs(j-k)*v+j*工资  v表示解雇或者雇佣的权值,由j,k相对大小决定
注意点:
1.要知道每月需要工人的max和min(保证每月雇佣人数在这个集合之间,[min,max]),这样每个月雇佣的人数不同,花费也不同,才可以求解最优解
2.初始化 第一个月的时候需要手动初始化,拿样例说,dp[1][9]第一个月雇佣9个人的费用(雇佣费加工资).......................dp[1][11]第一个月雇佣11个人的费用(雇佣费加工资),需要手动初始化
3.最有解是在dp[n][j]中找最小的,j属于[min,max]集合
 
重点:前面一个月雇佣多少人使得前面月份加上这个月份的花费最小
 
代码如下:
#include<bits/stdc++.h>
using namespace std;
#define inf 9999999
int dp[][];
int a[];
int hire,salary,fire;
int main()
{
int n;
while(~scanf("%d",&n))
{
if(n==)
break;
scanf("%d %d %d",&hire,&salary,&fire);
int max_people=-inf,min_people=inf;
for(int i=; i<=n; i++)
{
scanf("%d",&a[i]);
max_people=max(max_people,a[i]);
min_people=min(min_people,a[i]);
}
//dp[i][j] 在第i个月的时候,雇佣j个人的总费用(雇佣费+工资) //dp初始化
memset(dp,0x3f,sizeof(dp));//无穷大
for(int j=min_people; j<=max_people; j++)
{
dp[][j]=hire*j+salary*j;
} for(int i=; i<=n; i++)
{
for(int j=a[i]; j<=max_people; j++)
{
int t=inf;
for(int k=a[i-]; k<=max_people; k++)
{
int v=hire;
if(k-j>)//解雇
{
v=fire;
}
int x=dp[i-][k]+abs(k-j)*v+j*salary;
t=min(t,x);
}
dp[i][j]=t;
}
}
int t=inf;
for(int j=; j<=max_people; j++)
{
t=min(t,dp[n][j]);
}
printf("%d\n",t);
}
}

ojbk,溜了溜了,吃饭去

 
 
 
 
 
 
 
 
 
 

HDU 1158(非常好的锻炼DP思维的题目,非常经典)的更多相关文章

  1. HDU 1158 Employment Planning (DP)

    题目链接 题意 : n个月,每个月都至少需要mon[i]个人来工作,然后每次雇佣工人需要给一部分钱,每个人每个月还要给工资,如果解雇人还需要给一笔钱,所以问你主管应该怎么雇佣或解雇工人才能使总花销最小 ...

  2. hdu 1158 dp Employment Planning

    Employment Planning Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u ...

  3. HDU 1024 Max Sum Plus Plus --- dp+滚动数组

    HDU 1024 题目大意:给定m和n以及n个数,求n个数的m个连续子系列的最大值,要求子序列不想交. 解题思路:<1>动态规划,定义状态dp[i][j]表示序列前j个数的i段子序列的值, ...

  4. HDU 1231 最大连续子序列 --- 入门DP

    HDU 1231 题目大意以及解题思路见: HDU 1003题解,此题和HDU 1003只是记录的信息不同,处理完全相同. /* HDU 1231 最大连续子序列 --- 入门DP */ #inclu ...

  5. hdu 4778 Gems Fight! 博弈+状态dp+搜索

    作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4102743.html 题目链接:hdu 4778 Gems Fight! 博弈+状态dp+搜 ...

  6. hdu 4514 并查集+树形dp

    湫湫系列故事——设计风景线 Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Tot ...

  7. hdu 3247 AC自动+状压dp+bfs处理

    Resource Archiver Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 100000/100000 K (Java/Ot ...

  8. hdu 2825 aC自动机+状压dp

    Wireless Password Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  9. hdu 3433 A Task Process 二分+dp

    A Task Process Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) T ...

随机推荐

  1. C#迭代器、装箱/拆箱、重载等

    迭代器 迭代器是什么? 迭代器是作为一个容器,将要遍历的数据放入,通过统一的接口返回相同类型的值. 为什么要用迭代器? 为何了为集合提供统一的遍历方式,迭代器模式使得你能够获取到序列中的所有元素而不用 ...

  2. BZOJ2656 [Zjoi2012]数列

    Description 小白和小蓝在一起上数学课,下课后老师留了一道作业,求下面这个数列的通项公式: $$\begin{aligned}A_0 &= 0\\A_1 &= 1\\A_{2 ...

  3. vue指令示例合集

    vue所有指令练习合集.这是个html文件,用chrome打开可查看结果. <!DOCTYPE html> <html lang="en" xmlns:v-on= ...

  4. JavaScript的进阶之路(四)理解对象1

    对象是JavaScript的基本数据类型.简单的名值对组成了对象,BUT:还可以从一个被称为原型的对象继承属性,对象的方法通常就是继承的属性. 对象最常见的用法有:创建.设置.查找.删除.检测.枚举它 ...

  5. ORA-16014: log 3 sequence# 540 not archived, no available destinations

    https://blog.csdn.net/zonelan/article/details/7329369

  6. VMware虚拟机上配置CentOS联网

    转自https://www.cnblogs.com/cindy-cindy/p/6784536.html 1.首先保证虚拟机的网络适配器为NAT模式 2.设置虚拟机的“编辑”-->“虚拟网络编辑 ...

  7. 微信小程序开发11-HTTPS网络通信(重点)

    1.OneNET平台支持https,将HTTP头部改成https://api.heclouds.com即可(重点!!!!!!!!) 2.如果我们需要从 https://test.com/getinfo ...

  8. 反射报错java.lang.IllegalArgumentException: wrong number of arguments

    class Person{ private String name ; private String sex ; public Person(){ System.out.println("c ...

  9. .net core系列之《将.net core应用部署到Ubuntu》

    1.首先准备一个演示项目. 2.然后将这个项目用FileZilla工具上传到Ubuntu中. 3.进入目标文件,接下来有两种方法来部署项目 a.用dotnet run命令 root@hhz-virtu ...

  10. [翻译] IQAudioRecorderController

    IQAudioRecorderController IQAudioRecorderController is a drop-in universal library allows to record ...