zoukankan      html  css  js  c++  java
  • 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


    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;
    }
  • 相关阅读:
    动态改变shiro的Principal属性
    有邻App覆盖3000多个小区成杭州用户量最大的邻里分享经济平台 杨仁斌:开创新社区时代
    "有邻"创始人:APP覆盖杭州千余小区 却还没认真想过赚钱的事
    Shell if 条件判断
    大关小学和卖鱼桥小学哪个好 杭州重点小学对比
    测试覆盖率 Java 覆盖率 Jacoco 插桩的不同形式总结和踩坑记录
    使用Jacoco获取 Java 程序的代码执行覆盖率
    Android Studio Error running app: No target device found 问题
    android studio连接雷电模拟器
    Android Studio 下载Gradle 超时解决方案
  • 原文地址:https://www.cnblogs.com/Load-Star/p/12662429.html
Copyright © 2011-2022 走看看