Problem Description
A project manager wants to determine the number of the workers needed in every month. He does know the minimal number of the workers needed in each month. When he hires or fires a worker, there will be some extra cost. Once a worker
is hired, he will get the salary even if he is not working. The manager knows the costs of hiring a worker, firing a worker, and the salary of a worker. Then the manager will confront such a problem: how many workers he will hire or fire each month in order
to keep the lowest total cost of the project.
Input
The input may contain several data sets. Each data set contains three lines. First line contains the months of the project planed to use which is no more than 12. The second line contains the cost of hiring a worker, the amount
of the salary, the cost of firing a worker. The third line contains several numbers, which represent the minimal number of the workers needed each month. The input is terminated by line containing a single ‘0‘.
Output
The output contains one line. The minimal total cost of the project.
Sample Input
3 4 5 6 10 9 11 0
题意:
假如你是一个项目经理,在启动某个项目的时候涉及到雇佣工人的问题,已知出了工人每个月的固定工资外,在雇佣和解雇的时候需要额外向工人付一定费用,问如何安排才能使一个项目总花费最少.每组测试数据三行,第一行仅一个正数表示这个项目的持续时间(单位:月),第二行三个整数分别表示 雇佣,工资,解雇的费用.三行为该项目在每个月至少需要的工人数量.输出这个项目的最小总费用.
分析:不多说,dp!!
状态转移方程式:
dp[ i ][ j ] = min( dp[ i-1 ][ k ])+extr(k,j)+j*pay; ( k=a[ i-1 ]~max )
代码:
#include<stdio.h> #define inf 9999999; int a[13],dp[13][100000],in,out,pay; int extra(int a,int b) { if(a>b) return out*(a-b); return in*(b-a); } int main() { int i,j,k,n; while(scanf("%d",&n),n) { scanf("%d%d%d",&in,&pay,&out); for(i=1;i<=n;i++) scanf("%d",&a[i]); int max=0; for(i=1;i<=n;i++) { if(a[i]>max) max=a[i]; } for(i=1;i<=n;i++) for(j=a[i];j<=max;j++) { dp[i][j]=999999; if(i==1)dp[i][j]=extra(0,j)+j*pay; else { for(k=a[i-1];k<=max;k++) if(dp[i][j]>dp[i-1][k]+extra(k,j)+j*pay) dp[i][j]=dp[i-1][k]+extra(k,j)+j*pay; } } int min=inf; for(i=a[n];i<=max;i++) if(dp[n][i]<min) min=dp[n][i]; printf("%d\n",min); } return 0; }