hdoj1158 Employment Planning (DP)

题目:http://acm.hdu.edu.cn/showproblem.php?pid=1158

题意:

        公司完成一个项目需要n个月,每个月给出了最少计划人数需求,于是在不同的月份需要hire员工或者fire员工来既满足工程需求又减少公司花费,给定hire一个员工的花费、每个员工的月薪salary、fire一个员工的花费,求计划得到的最少花费。

思路:

        第一个月是需要支付hire所有员工的费用,而最后一个月是合同到期,不需要支付fire所有员工的费用,每个月都要付工资;第i个月计划需要最少人数为j=month[i];综合所有月份每个月最多人数需求为needmax,也就是所有人数需求中的最大值;于是每个月的人数计划范围为[j,needmax],第i个月计划k个人(j<=k<=needmax),则前i个月的花费为cost[i][k],那么cost[i][x]=min{cost[i-1][k]+(x-k)*hirecost+x*salary}(j<=k<=needmax),这里的min是比较k变动时得到的大括号里的值,cost[i-1][k]表示前i-1个月计划k个人的最少花费,cost[i][x]表示前i个月计划x个人的最少花费,(x-k)*hirecost表示hire花费,根据人数情况应该还有(k-x)*firecost表示fire花费,x*salary表示月薪;第一个月的花费需要初始化cost[1][k]=(salary+hire)*k,(j<=k<=needmax)。

#include<stdio.h>
int main()
{
	int n,i,j,k,needmax,minans,need;
	int hire,salary,fire;
	int month[13]={0},cost[13][10000]={0};
	while(scanf("%d",&n)&&n!=0)
	{
		scanf("%d %d %d",&hire,&salary,&fire);
		needmax=-1;
		for(i=1;i<=n;i++)
		{
			scanf("%d",&month[i]);
			if(month[i]>needmax)
				needmax=month[i];
		}
		for(i=month[1];i<=needmax;i++)
			cost[1][i]=(salary+hire)*i;
		for(i=2;i<=n;i++)
		{
			for(j=month[i];j<=needmax;j++)
			{
				minans=1000000000;
				for(k=month[i-1];k<=needmax;k++)
				{
					if(j>k)
						need=salary*j + hire*(j-k) + cost[i-1][k];
					else 
						need=salary*j + fire*(k-j) + cost[i-1][k];
					if(need < minans)
						minans=need;
				}
				cost[i][j]=minans;
			}
		}
		minans=1000000000;
		for(i=month[n];i<=needmax;i++)
		{
			if(cost[n][i] < minans)
				minans=cost[n][i];
		}
		printf("%d\n",minans);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值