题意:已知雇佣员工花费(h)、解雇员工花费(f)、员工每月薪水(s),员工未被解雇的话即使未工作也要付薪水,现知道每个月需要几名员工,求最低花费。

很显然,刷 DP 专题的我早早地就意识到这是一道 DP 题(呵呵,废话你在刷DP```),我最开始的思路是这样的,开一个一维数组 dp [ i ]  来记录第 i 个月的最低花费情况,同时另开一个平行数组记录该情况下的人数,通过第 i 月的需求人数与上个月的最优情况的人数比较,进行 DP 。但是很快我就发现,情况的种类很多很复杂,并且在第 i 个月的需求人数超过上个月人数时,我必须考虑到是否可能在更前面就不解雇员工维持到第 i 月,很明显我的想法并不可行。紧接着,我就在往之前学过的 DP 算法考虑,很显然,状压 DP 是考虑有多个互不相关的事物需要考察是否在某个状态时使用,与本题不符,而记忆化搜索又需要又一些固定步骤来进行 dfs ,也不是这题的情况。纠结了很久之后,我还是无奈地看了题解```

果然是智商上的压制啊!这题并没有涉及新的什么算法,没有超出我已学的东西,所以本应该是我可以推出来的,可是我却没有想到这样的做法,果然还是有很长的路要走啊。

解法是这样的,在读取每月需求人数 a [ i ] 的时候就记录下需求人数的最大值 b ,也就是整个过程中最多需要 b 人,开一个二维数组 dp , dp [ i ] [ j ]  表示第 i 月雇佣了 j 人的最小花费金额,由于每个月至少要有该月需求人数 a [ i ] 名员工,所以 j 的范围就是从 a [ i ] 到 b , i = 1 时直接初始化 dp [ 1 ] [ j ] ,都等于 j * ( h + s ),从第二个月开始,每个月的每种人数情况就是从上个月的所有人数情况转变来的最小值:

dp [ i ] [ j ] = min ( dp [ i ] [ j ] , dp [ i - 1 ] [ k ] + mon ( k , j ) + j * s);a [ i - 1 ] <= k <= b;

即当(第 i - 1 月有 k 个人时最小花费 + 从 k 人变为 j 人时的雇佣/解雇花费 + 第 i 月时 j 名员工的总工资)比 dp [ i ] [ j ] 小的时候就用这个值更新 dp [ i ] [ j ];

 #include<stdio.h>
#include<string.h>
#define min(a,b) a<b?a:b
#define max(a,b) a>b?a:b
#define inf 0x3f3f3f3f
int a[],dp[][],h,s,f; int mon(int last,int now){
if(now<last)return (last-now)*f;
if(now>last)return (now-last)*h;
return ;
} int main(){
int T;
while(scanf("%d",&T)!=EOF&&T!=){
int i,j,k,l=inf,b=;
scanf("%d%d%d",&h,&s,&f);
for(i=;i<=T;i++){
scanf("%d",&a[i]);
if(a[i]>b)b=a[i];
if(a[i]<l)l=a[i];
}
// printf("T=%d h=%d %d %d ",T,h,s,f);
for(j=a[];j<=b;j++){
dp[][j]=j*h+j*s;
// printf("%d ",dp[1][j]);
}
for(i=;i<=T;i++){
for(j=a[i];j<=b;j++){
dp[i][j]=inf;
for(k=a[i-];k<=b;k++){
dp[i][j]=min(dp[i][j],dp[i-][k]+mon(k,j)+j*s);
}
}
}
l=inf;
for(i=a[T];i<=b;i++)if(dp[T][i]<l)l=dp[T][i];
printf("%d\n",l);
}
return ;
}

hdu1158 dp经典题的更多相关文章

  1. HDU 2196 Computer 树形DP 经典题

    给出一棵树,边有权值,求出离每一个节点最远的点的距离 树形DP,经典题 本来这道题是无根树,可以随意选择root, 但是根据输入数据的方式,选择root=1明显可以方便很多. 我们先把边权转化为点权, ...

  2. 51nod 1353 树 | 树形DP经典题!

    51nod 1353 树 | 树形DP好题! 题面 切断一棵树的任意条边,这棵树会变成一棵森林. 现要求森林中每棵树的节点个数不小于k,求有多少种切法. 数据范围:\(n \le 2000\). 题解 ...

  3. POJ 1155 TELE 背包型树形DP 经典题

    由电视台,中转站,和用户的电视组成的体系刚好是一棵树 n个节点,编号分别为1~n,1是电视台中心,2~n-m是中转站,n-m+1~n是用户,1为root 现在节点1准备转播一场比赛,已知从一个节点传送 ...

  4. Vijos1057 盖房子(DP经典题)

    之前没有怎么刷过dp的题,所以在此学习了~(感谢walala大神的思路,给了我很大的启发) 也算是自己学习的另一种dp题型吧 先贴上状态转移方程: if(a[i][j]) f[i][j]=min(f[ ...

  5. 二维状压DP经典题

    炮兵阵地 题目链接 题目大意:在n*m的地图上放置炮兵,每个炮兵的攻击范围是上下左右两格内,有两种不同的地形,山地(用"H" 表示),平原(用"P"表示),只有 ...

  6. POJ:2385-Apple Catching(dp经典题)

    Apple Catching Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 14311 Accepted: 7000 Descr ...

  7. HDU 2196 Computer 树形DP经典题

    链接:http://acm.hdu.edu.cn/showproblem.php? pid=2196 题意:每一个电脑都用线连接到了还有一台电脑,连接用的线有一定的长度,最后把全部电脑连成了一棵树,问 ...

  8. POJ 2955 Brackets --最大括号匹配,区间DP经典题

    题意:给一段左右小.中括号串,求出这一串中最多有多少匹配的括号. 解法:此问题具有最优子结构,dp[i][j]表示i~j中最多匹配的括号,显然如果i,j是匹配的,那么dp[i][j] = dp[i+1 ...

  9. HihoCoder - 1048 状压DP 经典题

    hihocoder题解说的十分清晰了,这份代码就是从讲解里学习的 方案数就是不断枚举合法状态下横放竖放或两者均可 合法判断的依据是记录当前行和下一行的状态 防止重复枚举的方法是先按行后按列 递归基瞎写 ...

随机推荐

  1. PL/SQL : Procedural Language / Structual Query Language and it is an exrension to SQL.

    SQL is not very flexible and it cannot be made to react differently to differing sutuations easily. ...

  2. Unity场景道具模型拓展自定义编辑器

    (一)适用情况 当游戏主角进入特定的场景或者关卡,每个关卡需要加载不同位置的模型,道具等.这些信息需要先在unity编辑器里面配置好,一般由策划干这事,然后把这些位置道具信息保存在文件,当游戏主角进入 ...

  3. 学习MVC的一些随笔简单记录

    1 视图本身没有它所要显示的数据,视图的数据源始终是控制器 3 游戏的进行是模型的一部分,不是控制器的一部分 4 模型关于游戏是什么,在模型中封装游戏进行的逻辑,模型对用户界面一无所知,里面没有任何同 ...

  4. C++ primer的第二章的主要内容

    这第二章主要是介绍了C++中基本的内置数据类型:整型与浮点型.介绍了什么是变量的过程中了解到了左值与右值的概念.左值是可以出现在赋值语句的左边或者右边,也就是说可以放在等号的左右两边,而右值只能是出现 ...

  5. BZOJ 1912 巡逻

    重赋边权. #include<iostream> #include<cstdio> #include<cstring> #include<algorithm& ...

  6. AngularJS基本指令

    <!doctype html> <html  ng-app> <head>   <meta charset="UTF-8">   & ...

  7. ios oc ui 路径和颜色设置--崩溃解决方案

    - (id)init{ self = [super init]; if (self) { _lineColor = CGColorCreateCopy([UIColor whiteColor].CGC ...

  8. Redis - set类型操作

    set类型操作 设置操作:sadd:        sadd key value        给指定的key添加元素,重复返回0表示添加失败. srem:         srem key valu ...

  9. POJ3107 (树的重心)

    ; INF=; type arr=record u,v,nt:longint; end; arr1=..maxn] of longint; ..maxn*] of arr; lt:..maxn] of ...

  10. Codis 集群搭建

    Codis 集群搭建 1 安装go1.3.1 CentOS 7.0 安装go 1.3.1 1.1 下载go安装包 golang中国上下载 下载到Downloads下 1.2 解压 tar -zxf g ...