标签:des style blog io ar os sp java for
Asia 1997, Shanghai (Mainland China)
题目大意:老板想要决定M个月每个月需要的工人数,已知雇佣一个工人的价格,
工人的月薪,解雇一个工人的价格,又知道M个月每个月至少需要多少个工人。问:
怎样雇佣工人,才能使得满足M个月工人需求的同时,付出最少的钱。
思路:在M个月中求出最大的需求人数Max,那么无论下个月需要多少个工人,最多
雇佣Max个工人也就够了。
状态转移方程:dp[i][j] = min(dp[i-1][k] + cost)(num[i-1] <=k <= Max)
意思是:第i个月雇佣j个人 = 当上个月雇佣k个人时的最小花费 + 雇佣或解雇所需要
的花费这样三重循环遍历得出解雇。第一层代表第i个月,第二层代表第i月雇佣j个人
,第三层代表第i-1月雇佣k个人。最里层循环得出dp[i][j]。最后当第M个月的最小花
费就是将dp[M][i](num[M]<=i<=Max)遍历一遍求得M个月最小花费。
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; //dp[i][j] = min(dp[i-1][k] + cost)(num[i-1] <=k <= Max) int num[15],dp[15][1100],hire,fire,salary; int main() { int M,Max,Min,temp; while(~scanf("%d",&M) && M) { scanf("%d%d%d",&hire,&salary,&fire); Max = 0; for(int i = 1; i <= M; i++) { scanf("%d",&num[i]); if(num[i]>Max) Max = num[i]; } for(int i = num[1]; i <= Max; i++) dp[1][i] = (hire+salary)*i; for(int i = 2; i <= M; i++) { for(int j = num[i]; j <= Max; j++) { Min = 0xffffff0; for(int k = num[i-1];k <= Max; k++) { if(k > j) temp = dp[i-1][k] + fire*(k-j) + salary*j; else temp = dp[i-1][k] + hire*(j-k) + salary*j; if(temp < Min) Min = temp; } dp[i][j] = Min; } } int ans = 0xffffff0; for(int i = num[M]; i<= Max; i++) ans = min(ans,dp[M][i]); printf("%d\n",ans); } return 0; }
HDU1158_Employment Planning【DP】
标签:des style blog io ar os sp java for
原文地址:http://blog.csdn.net/lianai911/article/details/41542923