标签: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