[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
浙公网安备 33010602011771号