又一次看题解。

万事开头难,我想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. React Native 简介:用 JavaScript 搭建 iOS 应用(2)

    [编者按]本篇文章的作者是 Joyce Echessa--渥合数位服务创办人,毕业于台湾大学,近年来专注于协助客户进行 App 软体以及网站开发.本篇文章中,作者介绍通过 React Native 框 ...

  2. HTML5 webSQL

    https://www.ibm.com/developerworks/cn/web/1108_zhaifeng_websqldb/   <!DOCTYPE HTML> <html&g ...

  3. POJ 1573

    #include<iostream> #include<stdio.h> #define MAXN 15 using namespace std; char _m[MAXN][ ...

  4. Linux网络编程10——使用UDP实现五子棋对战

    思路 1. 通信 为了同步双方的棋盘,每当一方在棋盘上落子之后,都需要发送给对方一个msg消息,让对方知道落子位置.msg结构体如下: /* 用于发给对方的信息 */ typedef struct t ...

  5. 深入理解javascript:揭秘命名函数表达式

    这是一篇转自汤姆大叔的文章:http://www.cnblogs.com/TomXu/archive/2011/12/15/2288411.html 前言 网上还没用发现有人对命名函数表达式进去重复深 ...

  6. SSH 使用JUnit测试

    前提是引入两个包:org.springframework.test-3.1.3.RELEASE和JUnit4. package com.qk.test; import javax.annotation ...

  7. jmeter if 控制器

    判断变量值是不是为空(有没有被赋值): "${jd_aid}"!="\${jd_aid}"

  8. 深入剖析阿里巴巴云梯YARN集群

    我的一篇文章<深入剖析阿里巴巴云梯YARN集群> 已经发表在程序员2013年11月刊中, 原文链接为http://www.csdn.net/article/2013-12-04/28177 ...

  9. Project Euler P105:Special subset sums: testing 特殊的子集和 检验

    Special subset sums: testing Let S(A) represent the sum of elements in set A of size n. We shall cal ...

  10. GDB下查看内存命令(x命令)

    http://blog.csdn.net/allenlinrui/article/details/5964046 可以使用examine命令(简写是x)来查看内存地址中的值.x命令的语法如下所示: x ...