题意 : n个月,每个月都至少需要mon[i]个人来工作,然后每次雇佣工人需要给一部分钱,每个人每个月还要给工资,如果解雇人还需要给一笔钱,所以问你主管应该怎么雇佣或解雇工人才能使总花销最小。
样例解释 : 3个月,雇佣一个工人需要4钱,每个工人每个月的工资是5钱,解雇一个工人需要6钱。然后这三个月每个月需要的工人数最少分别是10人9人11人。0结束输入
3
4 5 6
10 9 11
0
主管在一开始就招10个人并且第二个月不解雇,因为解雇比他工资贵,需要花费40+50+50 = 140,第三个月再雇佣一个4+55 = 59加起来就是199,这是最少的花费,因为其他都是比这个多的。
思路 : 我觉得吧,这道DP题挺复杂的,dp[i][j]代表前 i 个月里雇佣j个人需要的最小花费,然后接下来就要找前一个状态,前一个状态要找最小值,也就是说要看一下,这个月相比前一个月是否需要雇佣或者是解雇,都要算出来然后取最小值。
1 //HDU 1158 2 #include <stdio.h> 3 #include <string.h> 4 #include <iostream> 5 6 using namespace std ; 7 8 int cost[12][1010] ; 9 int mon[101] ; 10 int main() 11 { 12 int n ,a,b,c; 13 while(~scanf("%d",&n)) 14 { 15 if(n == 0) break ; 16 scanf("%d %d %d",&a,&b,&c) ; 17 int maxx = 0 ; 18 for(int i = 0 ; i < n ; i ++) 19 { 20 scanf("%d",&mon[i]) ; 21 maxx = max(maxx,mon[i]) ; 22 } 23 memset(cost,0,sizeof(cost)) ; 24 int minn = mon[0],minx ; 25 for(int j = minn ; j <= maxx ; j++) 26 cost[0][j] = a*j+b*j ; 27 for(int i = 1 ; i < n ; i++) 28 { 29 for(int j = mon[i] ; j <= maxx ; j++) 30 { 31 minx = 99999999 ; 32 for(int k = mon[i-1] ; k <= maxx ; k++) 33 { 34 if(j > k) 35 { 36 if(((j-k)*a+cost[i-1][k]+j*b) < minx) 37 minx = (j-k)*a+cost[i-1][k]+j*b ; 38 } 39 else 40 { 41 if(((k-j)*c+cost[i-1][k]+j*b) < minx) 42 minx = (k-j)*c+cost[i-1][k]+j*b ; 43 } 44 } 45 cost[i][j] = minx ; 46 } 47 minn = mon[i] ; 48 } 49 minx = 999999999 ; 50 for(int k = minn ; k <= maxx ; k++) 51 if(cost[n-1][k] < minx) 52 minx = cost[n-1][k] ; 53 printf("%d ",minx) ; 54 } 55 return 0 ; 56 }