HDU1158:Employment Planning(暴力DP)

Employment Planning

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 7097    Accepted Submission(s): 3034


php

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
 

 

Sample Output
199
 

 

Source
 
 
題意:
有多組數據,每組數據給出一個工程每月最少須要的工人數量,僱傭工人的花費,每月的工資,解僱工人的花費,求出最少花費的錢。
題解:
由題意最多十二個月能夠無腦暴力DP(測試數據真的很水……),枚舉出每月僱傭最少的人到最多的人的最少花費便可(與上個月的全部狀況進行比較)。
狀態轉移爲:
dp[i][f] = min(dp[i][f], dp[i - 1][h] + (f - h) * hire + f * salary);(上個月的人數少於等於need[i]的人數)
dp[i][f] = min(dp[i][f], dp[i - 1][h] + (h - f) * fire + f * salary);(上個月的人數多於need[i]的人數)
具體見代碼;
#define _CRT_SECURE_NO_DepRECATE
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <iostream>
#include <cmath>
#include <iomanip>
#include <string>
#include <algorithm>
#include <bitset>
#include <cstdlib>
#include <cctype>
#include <iterator>
#include <vector>
#include <cstring>
#include <cassert>
#include <map>
#include <queue>
#include <set>
#include <stack>
#define ll long long
#define INF 0x3f3f3f3f
#define ld long double
const ld pi = acos(-1.0L), eps = 1e-8;
int qx[4] = { 0,0,1,-1 }, qy[4] = { 1,-1,0,0 }, qxx[2] = { 1,-1 }, qyy[2] = { 1,-1 };
using namespace std;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
    int hire, salary, fire, need[20], dp[20][300], max, ans;
    while (cin >> n && n)
    {
        memset(dp, 0, sizeof(dp));
        max = 0;
        ans = INF;
        cin >> hire >> salary >> fire;
        for (int i = 0; i < n; i++)
        {
            cin >> need[i];
            max = ::max(need[i], max);//記錄最多須要的人
        }
        for (int i = need[0]; i <= max; i++)//先初始化第一個月須要的錢,枚舉從一月最少須要的人到最多須要的人
        {
            dp[0][i] = i * (hire + salary);
        }
        for (int i = 1; i < n; i++)
        {
            for (int f = need[i]; f <= max; f++)//枚舉從最少須要的人到最多須要的人的狀況花費的錢
            {
                dp[i][f] = INF;
                for (int h = need[i - 1]; h <= max; h++)//與上個月的每種狀況進行對比
                {
                    if (h <= f)//人數少於或等於須要的人數
                    {
                        dp[i][f] = min(dp[i][f], dp[i - 1][h] + (f - h) * hire + f * salary);
                    }
                    else//人數多於須要的人數
                    {
                        dp[i][f] = min(dp[i][f], dp[i - 1][h] + (h - f) * fire + f * salary);
                    }
                }
            }
        }
        for (int i = need[n - 1]; i <= max; i++)//找到最小值
        {
            ans = min(ans, dp[n - 1][i]);
        }
        cout << ans << endl;
    }
    return 0;
}
相關文章
相關標籤/搜索