又一次看题解。

万事开头难,我想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的更多相关文章

  1. HDU 1158 Employment Planning (DP)

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

  2. Hdu 1158 Employment Planning(DP)

    Problem地址:http://acm.hdu.edu.cn/showproblem.php?pid=1158 一道dp题,或许是我对dp的理解的还不够,看了题解才做出来,要加油了. 只能先上代码了 ...

  3. HDU 1158 Employment Planning【DP】

    题意:给出n个月,雇佣一个人所需的钱hire,一个人工作一个月所需要的钱salary,解雇一个人所需要的钱fire,再给出这n个月每月1至少有num[i]个人完成工作,问完成整个工作所花费的最少的钱是 ...

  4. hdu 1158 Employment Planning(DP)

    题意: 有一个工程需要N个月才能完成.(n<=12) 给出雇佣一个工人的费用.每个工人每个月的工资.解雇一个工人的费用. 然后给出N个月所需的最少工人人数. 问完成这个项目最少需要花多少钱. 思 ...

  5. 【HDOJ】1158 Employment Planning

    简单DP. #include <cstdio> #include <cstring> #include <cstdlib> #include <climits ...

  6. HDU 1158(非常好的锻炼DP思维的题目,非常经典)

    题目链接: acm.hdu.edu.cn/showproblem.php?pid=1158 Employment Planning Time Limit: 2000/1000 MS (Java/Oth ...

  7. hdu 1158 dp Employment Planning

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

  8. Employment Planning[HDU1158]

    Employment Planning Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...

  9. Employment Planning DP

    Employment Planning Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Othe ...

随机推荐

  1. 全栈式JavaScript

    如今,在创建一个Web应用的过程中,你需要做出许多架构方面的决策.当然,你会希望做的每一个决定都是正确的:你想要使用能够快速开发的技术,支持持续的迭代,最高的工作效率,迅速,健壮性强.你想要精益求精并 ...

  2. javascript 注意事项

    1.submit input 标签的 type里的submit是提交表单的按钮 提交时应注意 为 标签加上 “name=""”字段和form标签,才能达到想要的效果  2.正则表达 ...

  3. 错误处理--pure specifier can only be specified for functions

    错误处理--pure specifier can only be specified for functions 今天下载了log4cpp的源代码,在VC6下编译时出现错误: ..\..\includ ...

  4. Cpp多重继承会产生的问题

    多重继承常常被认为是 OOP 中一种复杂且不必要的部分.多重继承面临 crash 的场景并非难以想象,来看下面的例子. 1. 名称冲突 来看以下情况: 如果 Dog 类以及 Bird 类都有一个名为 ...

  5. 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 ...

  6. mysql之游标

    游标 行,也不存在每次一行地处理所有行的简单方法(相对于成批地处理它们).有时,需要在检索出来的行中前进或后退一行或多行.这就是使用游标的原因.游标( cursor)是一个存储在MySQL服务器上的数 ...

  7. jmeter线程组之间传递参数

    JMeter 变量作用域局限于所属线程.这样设计是经过深思熟虑的,目的是让测试线程能够独立运转.有时候用户可能需要在不同线程间(可能属于同一个线程组,也可能不属于同一个线程组)传递变量. 其中一种方法 ...

  8. linux下对普通用户设置文件访问控命令之setfacl

    命令名 setfacl  -设置文件访问控制列表 常用用法:setfacl [-bkRd] [{-m|-x} acl参数] 目标文件名 命令的常用参数 -m 设置后续的acl参数给文件使用(常用). ...

  9. C# winform post请求数据

    刚到公司混的时候,老板要求实现一个从C#的windows应用程序传参数到一个网页,然后这个网页不显示出来,但能把数据返回给应用程序的功能,问了好多人,找了好多资料,都搞不定,后来还是在老板的帮助下搞定 ...

  10. C#计算时间差值

    /// <summary> /// 计算时间差值 /// </summary> /// <param name="DateTime1">< ...