[HDU] 1158 Employment Planning

题目链接:

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

方法:

设f(n,i)表示第i个月介绍还保留着n需要的最少钱,设max需要人数最多的哪个月所要的人数,needed[i]为第i月需要的人数。

    

     {

      n*hireCost + n*hireSalary; i==1 && needed[1]<=n<=max

f(n,i) =

      min(   {n>=lr ? (hireCost*(n-lr) +n*hireSalary) : (fireCost*(lr-n) +n*hireSalary) ;  |  lr是上个剩余的人数} );i>1 && needed[i]<=n<=max

     }

问题的最终解为:

min({F(n,12) | needed[12]<=n<=max})

代码:

#include<iostream>
#include<queue>
//#include<map>
//#include<string>
//#include <algorithm>
using namespace std;
int const MAX =0x3f3f3f3f;
int const MIN=-1;
int hcost,scost,fcost,needed[13];
int multple(int x,int y)
{
	if(x>=y)
		return (x-y)*hcost;
	else
		return (y-x)*fcost;
}
int main()
{
	int monthCount=0;
 
	int dp[105][13];
	while(scanf("%d",&monthCount) && monthCount!=0)
	{
		int i=1;
		memset(dp,0,sizeof(dp));
		int pcount,maxNeed=MIN;
		scanf("%d %d %d",  &hcost,&scost,&fcost);
		while(i<=monthCount)
		{
			scanf("%d",&pcount);
			if(maxNeed<pcount)
				maxNeed=pcount;
			needed[i]=pcount;
			i++;
		}
		for(int j = needed[1];j<=maxNeed;j++)
		{
			dp[j][1]=j*(hcost+scost);
		}
		for(int i = 2;i<=monthCount;i++)
		{
			for(int j = needed[i];j<=maxNeed;j++)
			{
				int t = MAX;
				for(int k = needed[i-1];k<=maxNeed;k++)
				{
					int t_re = dp[k][i-1]+ multple(j,k)+j*scost;
					if(t_re<t)
						t=t_re;
				}
				dp[j][i]=t;
			}
		}
			//for(int i = 1;i<=maxNeed;i++)
			//{
			//	for(int j = 1;j<=monthCount;j++)
			//	{
			//		cout << dp[i][j]<<" ";
			//	}
			//	cout<<endl;
			//}
		int re = MAX;
		for(int i = needed[monthCount];i<=maxNeed;i++)//在最终最优的时候还有一次最优解 的查找
		{
			if(dp[i][monthCount]<re)
				re = dp[i][monthCount];
		}
		cout<<re<<endl;
	}	 
	return 0;
} 

感谢:具有暴力性质的dp

原文地址:https://www.cnblogs.com/kbyd/p/3160891.html