题目大意: 一个公司在n个月里需要 a[1] , a[2]~~ a[n] 个人 , 招一个人,一个人每个月的工资和解雇一个人分别要花费 hire ,salary , fire的金钱,求n个月里花费的最小金额。
解题思路:dp
要使得 n 个月的时候钱最小,那么 n-1 的钱也是最小的。
如果n 个月需要的人数大于 n-1 个月需要的人数,则 dp[n][k] = dp[n-1][k] + (j-k)*hire + j*salary ;
如果n 个月需要的人数 小于 n-1 个月需要的人数 ,则 dp[n][k] = dp[n-1][k]+(k-j)*fire + j*salary ;
感觉代码的大意就是,因为 不知道第一个月是 招多小人好,所以 要每一个都判一遍 , 然后再判第二个月招多小人合适 于是就有了 三个 for 循环。
最后因为不知道 招多小人最小,于是再在 month[ n ] 到 maxn 中找最小。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define inf 0x7ffffff
using namespace std;
int n,dp[13][1110],month[1110];
int hire,salary,fire;
int maxn,minn,sum;
int main()
{
int i,j,k,temp;
while(scanf("%d",&n)!=EOF&&n!=0)
{
memset(dp,0,sizeof(dp));
maxn=0;
scanf("%d%d%d",&hire,&salary,&fire);
for(i=1;i<=n;i++)
{
scanf("%d",&month[i]);
maxn=max(maxn,month[i]);
}
if(maxn==0)
{
printf("0\n");
continue;
}
for(i=month[1];i<=maxn;i++)
{
dp[1][i]=(hire+salary)*i;
}
for(i=2;i<=n;i++)
{
for(j=month[i];j<=maxn;j++)
{
minn=inf;
for(k=month[i-1];k<=maxn;k++)
{
if(j>=k)
{
temp=dp[i-1][k]+(j-k)*hire+j*salary;
}
else
{
temp=dp[i-1][k]+(k-j)*fire+j*salary;
}
minn=min(minn,temp);
}
dp[i][j]=minn;
}
}
sum=inf;
for(j=month[n];j<=maxn;j++)
{
if(sum>dp[n][j])
sum=dp[n][j];
}
printf("%d\n",sum);
}
return 0;
}