题意:已知雇佣员工花费(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. JAVA小记

    关于重写equals()方法和重写toString()方法,一般来说,Objects的默认子类都重写了这两个方法,直接利用就行了: 对于用户自定义的类,如果要用到这两方法,就必须在程序中重写.

  2. [转]Putty中文乱码解决方法

    from: http://www.putty.ws/putty-luanma putty使用的过程中,你是否遇到过putty出现中文乱码的情况呢?putty终端出现乱码,是情况,多数是由于系统或软件缺 ...

  3. POJ 2185 - Milking Grid (二维KMP)

    题意:给出一个字符矩形,问找到一个最小的字符矩形,令它无限复制之后包含原来的矩形. 此题用KMP+枚举来做. 一维的字符串匹配问题可以用KMP来解决.但是二维的就很难下手.我们可以将二维问题转化为一维 ...

  4. 高效的iOS宏定义

    iOS开发过程中使用一些常用的宏可以提高开发效率,提高代码的重用性:将这些宏放到一个头文件里然后再放到工程中的-Prefix.pch文件中(或者直接放到-Prefix.pch中)直接可以使用,灰常方便 ...

  5. new work

    果不其然,还是电子工程师适合我.

  6. OBJECT ARX 添加标注样式

    ////获得当前图形的标注样式表 AcDbDimStyleTable* pDimStyleTbl; acdbHostApplicationServices()->workingDatabase( ...

  7. java generic type

    java generic type: 类型安全.类型参数化.不需要强制转换

  8. mysql innoDB 与 myISAM

    转载文章 出处  http://www.pureweber.com/article/myisam-vs-innodb/ 使用MySQL当然会接触到MySQL的存储引擎,在新建数据库和新建数据表的时候都 ...

  9. Mousejack测试指南

    0x00 前言 近日,Bastille的研究团队发现了一种针对蓝牙键盘鼠标的攻击,攻击者可以利用漏洞控制电脑操作,他们将此攻击命名为MouseJack. 攻击者仅需要在亚马逊上以60美元购买设备,改造 ...

  10. compare:(字符串的大小比较)

    1.字符串的比较是按照ascall码进行比较的 比如A比a的值小, if([string1 compare:string2] == (以下描述)) 如果比较的结果是NSOrderedDescendin ...