题目链接:

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. mybatis-generator 动态生成实体对象、dao 以及相关的xml映射文件

    .新建maven空项目 2.修改pom.xml文件 <?xml version="1.0" encoding="UTF-8"?> <proje ...

  2. js生成qq客服在线代码

    说到QQ客服在线代码,随便那么百度谷歌一下就会出来,一般都是 <a target="blank" href="http://wpa.qq.com/msgrd?V=1 ...

  3. 洛谷P3384 树链剖分

    如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节点的值都加上z 操作2: 格式: 2 x ...

  4. 03.CSS选择器-->交集并集选择器

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. VC学习笔记---ATL MFC CLR三个库的区别

    MFC.ATL和CLR是VC2005内置的三大库,涵盖了Windows的各种开发方法和开发应用.当然关于C++开发的库不止这三个,不过这三个是微软推荐. 从编程所处层次而言,WIN32为最底层,其次是 ...

  6. 【疑难杂症01】TypeError: alert is not a function

    一.背景 话说今天在调试js的时候,碰到一个很奇怪的问题,现记录一下.当使用alert()函数弹出提示时,总是报错,你没看错,alert函数报错了. 二.详细说明 当时正在做一个关于告警的页面展示功能 ...

  7. python oop常用术语 继承 多态 封装

    面向对象优点 1.通过封装明确了内外 2.通过继承+多态在语言层面支持了归一化设计 抽象/实现 抽象指对现实世界问题和实体的本质表现,行为和特征建模,建立一个相关的子集,可以用于 绘程序结构,从而实现 ...

  8. linux 加jre环境变量

    1.vi /etc/profile 2.未行添加 export JAVA_HOME=/usr/local/java export CLASSPATH=.:$JAVA_HOME/lib/tools.ja ...

  9. 毕向东_Java基础视频教程第19天_IO流(18~19)

    第19天-18-IO流(流操作规律 - 1) 通过三个步骤来明确"流操作"的规律: 明确数据流的"源和目的" 源, 输入流: InputStream/Reade ...

  10. ArcGIS的网络分析

    ArcGIS的网络分析分为两类:传输网络(Network Analyst)和效用网络(Utility Network Analyst). 一.从应用上来考虑: 1.传输网络常用于道路.地铁等交通网络分 ...