题意:
一个项目需要n个月完成,hire一个人所需的费用、每个人一个月的工资、fire一个人所需的费用。
以及每个月至少要雇佣xi个人。
求完成项目所需要的最少投入资金。
分析:
状态转移方程:dp[i][j]=min(dp[i-1][k]+j*s+k>l?(k-j)*fire:(j-k)*hire) p[i-1]<=k<=maxp
dp[i][j]表示到i月为止,第i月雇佣j个人所需要的资金。
(i表示月,j表示人数)
p[i]表示第i个月需要的最少人数,maxp是所需的最大人数。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int dp[13][1010];
int p[1010];
int main()
{
int n,hire,salary,fire,ans,maxp;
while(scanf("%d",&n)!=EOF)
{
if(n==0)
break;
scanf("%d%d%d",&hire,&salary,&fire);
maxp=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&p[i]);
if(p[i]>maxp)
maxp=p[i];
}
memset(dp,0x3f,sizeof(dp));
for(int i=p[1];i<=maxp;i++)
dp[1][i]=i*(hire+salary);
for(int i=2;i<=n;i++)
{
for(int j=p[i];j<=maxp;j++)
{
if(p[i-1]<j)
dp[i][j]=min(dp[i][j],dp[i-1][p[i-1]]+salary*j+(j-p[i-1])*hire);
else
dp[i][j]=min(dp[i][j],dp[i-1][p[i-1]]+salary*j+(p[i-1]-j)*fire);
for(int k=p[i-1];k<=maxp;k++)
{
if(k>j)
dp[i][j]=min(dp[i][j],dp[i-1][k]+salary*j+(k-j)*fire);
else
dp[i][j]=min(dp[i][j],dp[i-1][k]+salary*j+(j-k)*hire);
}
}
}
ans=10000000;
for(int i=p[n];i<=maxp;i++)
{
if(ans>dp[n][i])
ans=dp[n][i];
}
printf("%d\n",ans);
}
return 0;
}