C语言动态规划(8)___雇佣工人(HDU 1158)

Problem Description

A project manager wants to determine the number of the workers needed in every month. He does know the minimal number of the workers needed in each month. When he hires or fires a worker, there will be some extra cost. Once a worker
is hired, he will get the salary even if he is not working. The manager knows the costs of hiring a worker, firing a worker, and the salary of a worker. Then the manager will confront such a problem: how many workers he will hire or fire each month in order
to keep the lowest total cost of the project.

Input

The input may contain several data sets. Each data set contains three lines. First line contains the months of the project planed to use which is no more than 12. The second line contains the cost of hiring a worker, the amount
of the salary, the cost of firing a worker. The third line contains several numbers, which represent the minimal number of the workers needed each month. The input is terminated by line containing a single ‘0‘.

Output

The output contains one line. The minimal total cost of the project.

Sample Input

3
4 5 6
10 9 11
0

题意:

假如你是一个项目经理,在启动某个项目的时候涉及到雇佣工人的问题,已知出了工人每个月的固定工资外,在雇佣和解雇的时候需要额外向工人付一定费用,问如何安排才能使一个项目总花费最少.每组测试数据三行,第一行仅一个正数表示这个项目的持续时间(单位:月),第二行三个整数分别表示 雇佣,工资,解雇的费用.三行为该项目在每个月至少需要的工人数量.输出这个项目的最小总费用.

分析:不多说,dp!!

状态转移方程式:

dp[ i ][ j ] = min( dp[ i-1 ][ k ])+extr(k,j)+j*pay;   ( k=a[ i-1 ]~max )

代码:

#include<stdio.h>
#define inf 9999999;
int a[13],dp[13][100000],in,out,pay;
int extra(int a,int b)
{
	if(a>b)
		return out*(a-b);
	return in*(b-a);
}
int main()
{
	int i,j,k,n;
	while(scanf("%d",&n),n)
	{
		scanf("%d%d%d",&in,&pay,&out);
		for(i=1;i<=n;i++)
			scanf("%d",&a[i]);
		int max=0;
		for(i=1;i<=n;i++)
		{
			if(a[i]>max)
				max=a[i];
		}
		for(i=1;i<=n;i++)
			for(j=a[i];j<=max;j++)
			{
				dp[i][j]=999999;
				if(i==1)dp[i][j]=extra(0,j)+j*pay;
				else
				{
					for(k=a[i-1];k<=max;k++)
						if(dp[i][j]>dp[i-1][k]+extra(k,j)+j*pay)
							dp[i][j]=dp[i-1][k]+extra(k,j)+j*pay;
				}
			}
		int min=inf;
		for(i=a[n];i<=max;i++)
			if(dp[n][i]<min)
				min=dp[n][i];
		printf("%d\n",min);
	}
	return 0;
}
时间: 2024-10-14 20:50:53

C语言动态规划(8)___雇佣工人(HDU 1158)的相关文章

C语言动态规划(7)___过河(Vijos P1002)

Problem Description 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很讨厌踩在这些石子上.由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙可能到达的点看成数轴上的一串整点:0,1,--,L(其中L是桥的长度).坐标为0的点表示桥的起点,坐标为L的点表示桥的终点.青蛙从桥的起点开始,不停的向终点方向跳跃.一次跳跃的距离是S到T之间的任意正整数(包括S,T).当青蛙跳到或跳过坐标为L的点时,就算青蛙已经跳出了独木桥. 题目给出

C语言动态规划(6)___传纸条(Vijos P1493)

描述: 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法直接交谈了.幸运的是,他们可以通过传纸条来进行交流.纸条要经由许多同学传到对方手里,小渊坐在矩阵的左上角,坐标(1,1),小轩坐在矩阵的右下角,坐标(m,n).从小渊传到小轩的纸条只可以向下或者向右传递,从小轩传给小渊的纸条只可以向上或者向左传递. 在活动进行中,小渊希望给小轩传递一张纸条,同时希望小轩给他回复.班里每个

HDU 1158 Employment Planning (DP)

Problem Description A project manager wants to determine the number of the workers needed in every month. He does know the minimal number of the workers needed in each month. When he hires or fires a worker, there will be some extra cost. Once a work

HDU 1158 Employment Planning

题意:有一公司要工作n个月每个月需要至少p[i]个人工作,每个人的工资固定位m, 每雇佣一个人要花费h,每炒掉一个人要花费f.求完成n个月工作,公司最小的花费. 思路: Dp[i][j]为前i个月的留j个人的最优解;p[i]<=j<=Max{p[i]}; j>Max{p[i]}之后无意义,无谓的浪费 记Max_n=Max{p[i]}; Dp[i-1]中的每一项都可能影响到Dp[i],即使p[i-1]<<p[i] 所以利用Dp[i-1]中的所有项去求Dp[i]; 对于p[i]&

HDU 1158

AC自动机中的DP 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <string.h> 5 #include <string> 6 #include <queue> 7 #include <map> 8 using namespace std; 9 const int N=52*2; 10 char str[52],s1[

C语言记忆化搜索___漫步校园(Hdu 1428)

Problem Description LL最近沉迷于AC不能自拔,每天寝室.机房两点一线.由于长时间坐在电脑边,缺乏运动.他决定充分利用每次从寝室到机房的时间,在校园里散散步.整个HDU校园呈方形布局,可划分为n*n个小方格,代表各个区域.例如LL居住的18号宿舍位于校园的西北角,即方格(1,1)代表的地方,而机房所在的第三实验楼处于东南端的(n,n).因有多条路线可以选择,LL希望每次的散步路线都不一样.另外,他考虑从A区域到B区域仅当存在一条从B到机房的路线比任何一条从A到机房的路线更近(

C语言贪心(2)___田忌赛马(Hdu 1052)

Problem Description Here is a famous story in Chinese history. "That was about 2300 years ago. General Tian Ji was a high official in the country Qi. He likes to play horse racing with the king and others." "Both of Tian and the king have t

C语言_数学(1)___统计问题(Hdu 2563)

Problem Description 在一无限大的二维平面中,我们做如下假设: 1.  每次只能移动一格: 2.  不能向后走(假设你的目的地是"向上",那么你可以向左走,可以向右走,也可以向上走,但是不可以向下走): 3.  走过的格子立即塌陷无法再走第二次: 求走n步不同的方案数(2种走法只要有一步不一样,即被认为是不同的方案). Input 首先给出一个正整数C,表示有C组测试数据 接下来的C行,每行包含一个整数n (n<=20),表示要走n步. Output 请编程输出

C语言DFS(6)___八皇后问题(Hdu 2612)

Problem Description 在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上. 你的任务是,对于给定的N,求出有多少种合法的放置方法. Input 共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量:如果N=0,表示结束. Output 共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量. Sample Input 1 8 5 0 Sample Output 1 92 10 很经典的