雇佣计划

很久以前做的题,拎出来

Problem Description

一位管理项目的经理想要确定每个月需要的工人,他当然知道每月所需的最少工人数。当他雇佣或解雇一个工人时,会有一些额外支出。一旦一个工人被雇佣,即使他不工作,他也将得到工资。这位经理知道雇佣一个工人的费用,解雇一个工人的费用和一个工人的工资。

现他在考虑一个问题:为了把项目的费用控制在最低,他将每月雇佣多少个工人。

Input Format

共三行。

第一行为月数n(不超过12)。
第二行含雇佣一个工人的费用,一个工人的工资和解雇一个工人的费用(<=100)。
第三行含n个数,分别表示每月需要的工人数(<=1000)。每个数据之间有一个空格隔开。

Output Format

仅一行,表示项目的最小总费用。

Algorithm Design

贪心算法

Problem Analysis

这道题因素过于复杂,打爆搜不可能看出规律。两个可能的突破口:1.月数n非常小。2.工人的支出都是统一的。顺向思维,第一个工作月当然要雇佣需要的工人 数。接下来面临三种情况:1.工人缺少2.工人恰好3.工人冗余。前两种处理方式十分简单,缺就雇,不缺就照常。可见这题全部的难点都在一个问题上:怎么 处理工人冗余的情况。解不解雇?解雇几个人?仔细思考一下这个问题。

不难发现,这题其实还是存在最优解子结构和无后效性的,把工作月需要的工人想象成山高,而我们要处理的问题是峰谷之间的问题,这个时候处理几个工人并不重要,1,2,3,一直到峰差都是一样的处理,只是峰距不一样罢了

1.解雇,需要两(一)次费用:解雇费和雇佣费(如果之后还有山峰的话)

2.留用,既然留用,就不存在留用一段时间再解雇的情况,那是完全的亏损,而留用至少会让他待到下一个山峰,那时候又是另一个子问题不管,所以需要峰距*月薪

那么问题的重点已经呼之欲出:计算峰距

利用突破口1,穷举都是完全可以的,所以这个问题已经基本上被解决了。

一遍就过掉了~

Source Code

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 int n,hire,cut,paid,w[13],had,cost;
 6 //hire雇佣费,paid月薪,cut解雇费,had当前工人,cost总花费
 7 int main()
 8 {
 9     freopen("test.in","r",stdin);
10     freopen("test.out","w",stdout);
11     cin>>n>>hire>>paid>>cut;
12     for(int i=1;i<=n;i++)
13         cin>>w[i];
14     had=w[1],cost=(hire+paid)*w[1];//将第一月的工人全部招入
15     for(int i=2;i<=n;i++)    
16     {
17         cost+=paid*w[i];//将起码要工作的工人工资发下
18         if(w[i]>=had)
19         {
20             cost+=hire*(w[i]-had);
21             had=w[i];
22             continue;
23         }//如果工人数不够则补充
24         int gap=had-w[i];//计算多余的工人数
25         for(int j=1;j<=gap;j++)
26         {
27             int sub=n+1,cost1=0,cost2=0;
28             for(int k=i+1;k<=n;k++)
29                 if(w[k]>=w[i]+j)
30                 {
31                     sub=k;
32                     cost1=hire;//如果存在下一个山峰还要再雇佣一次
33                     break;
34                 }//针对多出的工人数找到第一个有用处的山峰
35             cost1+=cut,cost2=paid*(sub-i);
36 //解雇方案加上解雇费,留用方案加上工资
37             if(cost1>=cost2)cost+=paid;
38             else cost+=cut,had--;
39 //选择最适当的方案
40         }
41     }
42     cout<<cost<<endl;
43     return 0;
44 }
View Code
原文地址:https://www.cnblogs.com/qswx/p/9418946.html