题目链接:

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. 删除N天前的备份文件脚本(windows)

    D:\bat\forfiles.exe /p "D:\dmpbk" /s /m *.dmp /d -2 /c "cmd /c del @path" 解析: 使用 ...

  2. 如何使DIV居中

    小编我抛出一个问题: 有一个 div#wrapper 元素,高.宽度都未知.它其中有一个宽高都为 100px 的 div#box 元素,请你完成 CSS,使得 div#box 在 div#wrappe ...

  3. 收藏的几个关于php面向对象教程

    面向对象的分析方法是利用面向对象的信息建模概念,如实体.关系.属性等,同时运用封装.继承.多态等机制来构造模拟现实系统的方法,学会了面向对象思想,能够大大提高php编程开发效率!本篇文章php中文网将 ...

  4. 解决:Thinkphp3 返回中文内容出现乱码

  5. System Test GIS压力测试利器

    System Test是ESRI公司提供一个压力测试软件.能针对ArcGIS Server 地图服务.WMS服务.WFS服务.WCS服务接口进行压力测试.以下是一个针对ArcGIS Server 地图 ...

  6. Servlet - Reasource loading

    1. Load db3.properties String path = this.getServletContext().getRealPath("/WEB-INF/classes/db/ ...

  7. String和StringBuffer有什么区别

    首先,String和StringBuffer主要有2个区别: (1)String类对象为不可变对象,一旦你修改了String对象的值,隐性重新创建了一个新的对象,释放原String对象,StringB ...

  8. php下载远程大文件(获取远程文件大小)

    function download_file($url) { // $url = http://192.168.8.95/vm/download_file?downurl=http://192.168 ...

  9. react native学习资料

    一:基础学习: react-native中文文档(react native中文网,人工翻译,官网完全同步)http://react-native.cn/docs/getting-started.htm ...

  10. HTML5-入门。

    什么是HTML5? HTML5是超文本语言,不是编程语言,html5是html语言的最新版本,需要注意浏览器的兼容性问题. HTML5技术一般是指的是HTML5.CSS3.JavaScript三种技术 ...