题目链接:
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