首页 > 其他 > 详细

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

时间:2015-06-07 13:50:07      阅读:346      评论:0      收藏:0      [点我收藏+]

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

分析:开始我想的一维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 1000000007
using 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;
	}
}


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

原文:http://blog.csdn.net/ac_0_summer/article/details/46400101

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!