HDU 1158 Employment Planning

来源:互联网 发布:ubuntu源文件在哪 编辑:程序博客网 时间:2024/05/18 02:37



题意:有一公司要工作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]<=k<=Max_n,    当k<j时, 招聘;
当k>j时, 解雇 然后求出最小值
Dp[i][j]=min{Dp[i-1][k…Max_n]+(招聘,解雇,工资);    


#include<cstdio>#include<stdlib.h>#include<string.h>#include<string>#include<map>#include<cmath>#include<iostream>#include <queue>#include <stack>#include<algorithm>#include<set>using namespace std;#define INF 1e8#define eps 1e-8#define ll __int64#define maxn 100010#define mol 1000000007int dp[15][99999];int main(){int n,h,m,f;int p[15];while(scanf("%d",&n)&&n){scanf("%d%d%d",&h,&m,&f);int maxx=0,minn=99999;for(int i=1;i<=n;i++){scanf("%d",&p[i]);if(p[i]>maxx)maxx=p[i];if(p[i]<minn)minn=p[i];}for(int i=0;i<=n;i++)for(int j=minn;j<=maxx;j++)dp[i][j]=(i==0?0:INF);int fire,hire;for(int i=1;i<=n;i++){for(int j=p[i];j<=maxx;j++){if(i==1)dp[i][j]=dp[i-1][j]+j*(m+h);else {for(int k=p[i-1];k<=maxx;k++){hire=0;fire=0;if(k<j)hire=(j-k)*h;else fire=(k-j)*f;dp[i][j]=min(dp[i][j],dp[i-1][k]+hire+fire+j*m);}}}}int ans=INF;for(int i=p[n];i<=maxx;i++)if(dp[n][i]<ans) ans=dp[n][i];printf("%d\n",ans);}return 0;}



0 0