!HDU 1158 Employment Planning--DP--(二维)

来源:互联网 发布:开淘宝店投资多少钱 编辑:程序博客网 时间:2024/05/18 03:59

题意:列出每个月需要的员工数,已知每月工资、以及雇佣和开除员工的额外费用,求最小的预算。(只要员工不被开除就拿工资)

分析:开始我想的一维dp,结果在找状态转移方程的时候发现有很多情况要讨论,所以我就认为这题应该是一个贪心题,在准备打代码的时候发现贪心不能得出最优解,所以我就去搜题解了,原来是二维dp。记住一维要分很多情况的要用二维。

      dp[i][j]表示第i月用j个员工时前i月的最小预算,j从a[i]枚举到mx(n个月中需要的最多的员工数),状态转移方程:dp[i][j]=min(dp[i-1][k]+cost),其中a[i-1]<=k<=mx,           cost表示从dp[i-1][k]状态转移到dp[i][j]状态的开销;所以最终结果ans=min(dp[n][k]),a[n]<=k<=mx

代码:

#include<iostream>#define INF 1000000007using namespace std;int n,fire,salary,hire;int a[20],dp[20][200000];int main(){while(cin>>n){if(!n) break;cin>>hire>>salary>>fire;int mx=-1;for(int i=1;i<=n;i++){cin>>a[i];if(mx<a[i]) mx=a[i];    }    for(int i=a[1];i<=mx;i++)        dp[1][i]=hire*i+salary*i;for(int i=2;i<=n;i++){for(int j=a[i];j<=mx;j++){int mi=INF;for(int k=a[i-1];k<=mx;k++){    int tmp;if(k>j) tmp=dp[i-1][k]+(k-j)*fire+salary*j;else tmp=dp[i-1][k]+(j-k)*hire+salary*j;if(mi>tmp) mi=tmp;}dp[i][j]=mi;}}int mi=INF;for(int i=a[n];i<=mx;i++)   if(mi>dp[n][i]) mi=dp[n][i];    cout<<mi<<endl;}}


0 0
原创粉丝点击