HDU 1158 Employment Planning
又一次看题解。
万事开头难,我想DP也是这样的。
呵呵,不过还是有进步的。
比如说我一开始也是打算用dp[i][j]表示第i个月份雇j个员工的最低花费,不过后面的思路就完全错了。。
不过这里还有个问题,这样开数组j开多大比较好,难道要我开2^31-1这么大?
题解里面开了1000多,也许再小一点也能过吧。
因为有可能解雇一个人的花费比较大,所以某个月可能继续雇佣他这样总的算来是最省的。
所以第i个月可能雇佣的人数是从num[i] ~ NumMax。
首先对第一个月的费用初始化,就是(雇佣+薪水)×人数。
后面便是核心代码,
if(j < num[i - ])
dp[i][j] = dp[i - ][num[i - ]] + salary * j + (num[i - ] - j) * fire;
else
dp[i][j] = dp[i - ][num[i - ]] + salary * j + (j - num[i - ]) * hire;
这一句是为了后面的状态转移做准备,
先假设在上个月恰好雇num[i - 1]人的最小费用的基础上,人数多了就解雇,少了就雇佣是最省的。
然后再增加一个循环变量k,假如上个月多雇了一个人,那么这个月不用解雇也许可能更省。
for(int k = num[i - ] + ; k <= NumMax; ++k)
{
if(k > j)
dp[i][j] = min(dp[i][j], dp[i - ][k] + j * salary + (k - j) * fire);
else
dp[i][j] = min(dp[i][j], dp[i - ][k] + j * salary + (j - k) * hire);
}
最后就是输出最优解了,最优解有可能在数组最后一行的任何一个地方(还是那句话,假如上个月多雇了一个人,那么这个月不用解雇也许可能更省。)
所以要找到最后一行的最小值来输出。
总结:
注意:千万不要的在心情不平稳的时候敲代码,这样只会越敲越乱,与其去改还不如心平气和的从头开始敲,好有个完整的思路。
刚才9点多在教室里是时候因为要快熄灯了,而且这一天就在搞这一道题,还没完全弄明白。便有些心急,想着今天怎么也要把这道题
A出来。结果回宿舍改的时候各种错误,变量名打错,不等号搞反之类的。
不管是做题还是敲代码,平心静气,切记切记!
完整的AC代码:
#define LOCAL
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; int dp[][];
int num[]; int main(void)
{
#ifdef LOCAL
freopen("1158in.txt", "r", stdin);
#endif int n;
while(scanf("%d", &n) && n)
{
int i;
int fire, salary, hire;
int NumMax = ;
scanf("%d %d %d", &hire, &salary, &fire); for(i = ; i < n; ++i)
{
scanf("%d", &num[i]);
if(NumMax < num[i])
NumMax = num[i];
}
if(NumMax == )
{
printf("0\n");
continue;
}
for(i = num[]; i <= NumMax; ++i)
dp[][i] = i * (hire + salary); for(i = ; i < n; ++i)
{
for(int j = num[i]; j <= NumMax; ++j)
{
if(j < num[i - ])
dp[i][j] = dp[i - ][num[i - ]] + salary * j + (num[i - ] - j) * fire;
else
dp[i][j] = dp[i - ][num[i - ]] + salary * j + (j - num[i - ]) * hire; //考虑到与其解雇一个人还不如让他继续待下去的情况
for(int k = num[i - ] + ; k <= NumMax; ++k)
{
if(k > j)
dp[i][j] = min(dp[i][j], dp[i - ][k] + j * salary + (k - j) * fire);
else
dp[i][j] = min(dp[i][j], dp[i - ][k] + j * salary + (j - k) * hire);
}
}
} int ans = ;
for(i = num[i - ]; i <= NumMax; ++i)
ans = min(dp[n - ][i], ans);
printf("%d\n", ans);
}
return ;
}
代码君
HDU 1158 Employment Planning的更多相关文章
- HDU 1158 Employment Planning (DP)
题目链接 题意 : n个月,每个月都至少需要mon[i]个人来工作,然后每次雇佣工人需要给一部分钱,每个人每个月还要给工资,如果解雇人还需要给一笔钱,所以问你主管应该怎么雇佣或解雇工人才能使总花销最小 ...
- Hdu 1158 Employment Planning(DP)
Problem地址:http://acm.hdu.edu.cn/showproblem.php?pid=1158 一道dp题,或许是我对dp的理解的还不够,看了题解才做出来,要加油了. 只能先上代码了 ...
- HDU 1158 Employment Planning【DP】
题意:给出n个月,雇佣一个人所需的钱hire,一个人工作一个月所需要的钱salary,解雇一个人所需要的钱fire,再给出这n个月每月1至少有num[i]个人完成工作,问完成整个工作所花费的最少的钱是 ...
- hdu 1158 Employment Planning(DP)
题意: 有一个工程需要N个月才能完成.(n<=12) 给出雇佣一个工人的费用.每个工人每个月的工资.解雇一个工人的费用. 然后给出N个月所需的最少工人人数. 问完成这个项目最少需要花多少钱. 思 ...
- 【HDOJ】1158 Employment Planning
简单DP. #include <cstdio> #include <cstring> #include <cstdlib> #include <climits ...
- HDU 1158(非常好的锻炼DP思维的题目,非常经典)
题目链接: acm.hdu.edu.cn/showproblem.php?pid=1158 Employment Planning Time Limit: 2000/1000 MS (Java/Oth ...
- hdu 1158 dp Employment Planning
Employment Planning Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u ...
- Employment Planning[HDU1158]
Employment Planning Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- Employment Planning DP
Employment Planning Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Othe ...
随机推荐
- 全栈式JavaScript
如今,在创建一个Web应用的过程中,你需要做出许多架构方面的决策.当然,你会希望做的每一个决定都是正确的:你想要使用能够快速开发的技术,支持持续的迭代,最高的工作效率,迅速,健壮性强.你想要精益求精并 ...
- javascript 注意事项
1.submit input 标签的 type里的submit是提交表单的按钮 提交时应注意 为 标签加上 “name=""”字段和form标签,才能达到想要的效果 2.正则表达 ...
- 错误处理--pure specifier can only be specified for functions
错误处理--pure specifier can only be specified for functions 今天下载了log4cpp的源代码,在VC6下编译时出现错误: ..\..\includ ...
- Cpp多重继承会产生的问题
多重继承常常被认为是 OOP 中一种复杂且不必要的部分.多重继承面临 crash 的场景并非难以想象,来看下面的例子. 1. 名称冲突 来看以下情况: 如果 Dog 类以及 Bird 类都有一个名为 ...
- Good Bye 2015 A. New Year and Days 签到
A. New Year and Days Today is Wednesday, the third day of the week. What's more interesting is tha ...
- mysql之游标
游标 行,也不存在每次一行地处理所有行的简单方法(相对于成批地处理它们).有时,需要在检索出来的行中前进或后退一行或多行.这就是使用游标的原因.游标( cursor)是一个存储在MySQL服务器上的数 ...
- jmeter线程组之间传递参数
JMeter 变量作用域局限于所属线程.这样设计是经过深思熟虑的,目的是让测试线程能够独立运转.有时候用户可能需要在不同线程间(可能属于同一个线程组,也可能不属于同一个线程组)传递变量. 其中一种方法 ...
- linux下对普通用户设置文件访问控命令之setfacl
命令名 setfacl -设置文件访问控制列表 常用用法:setfacl [-bkRd] [{-m|-x} acl参数] 目标文件名 命令的常用参数 -m 设置后续的acl参数给文件使用(常用). ...
- C# winform post请求数据
刚到公司混的时候,老板要求实现一个从C#的windows应用程序传参数到一个网页,然后这个网页不显示出来,但能把数据返回给应用程序的功能,问了好多人,找了好多资料,都搞不定,后来还是在老板的帮助下搞定 ...
- C#计算时间差值
/// <summary> /// 计算时间差值 /// </summary> /// <param name="DateTime1">< ...