• POJ 1964 Cow Cycling(黑书 + DP经典 + 背包)


    题意:

    现在有 N 头奶牛, 每头奶牛的能量是E, 现在要奶牛们只要有一头完成跑D圈就完成任务。

    但是每次都要由一头奶牛领跑, 没有能量的奶牛可以退场或继续跟跑, 但是带头的奶牛体力消耗是: x*x laps/min, 跟跑的是x laps/min。

    现在要你计算出最短时间内完成任务。 (黑书 158 奶牛转圈)

    思路:

    1. dp[i][d][e] 表示第 i 只奶牛跑了 d 圈且能量消耗为 e 时,所需的最小分钟;

    2. 针对第 i 只奶牛是否领跑,又展开了讨论,如果不领跑,注意到一个性质:跑了多少圈就消耗多少能量,则有: dp[i][d][d] = dp[i-1][d][e];

    3. 如果第 i 只奶牛领跑,则考虑它领跑的速度是多少以及这 d 圈有多少圈是领跑的,可以利用完全背包的策略把代码简化为 O(N*D*E);

       dp[i][d][] = min(dp[i][d][], dp[i][d-k][] + 1); 相当于体积为 1 的物品价值为 1,看成完全背包,时间规模减少一维;

    4. 一开始我把转移方程式理解成了:dp[i][e][d] 表示第 i 只奶牛消耗能量值为 e 时且跑了 d 圈,所需的最小分钟,没有利用到完全背包的性质,见代码2 ;

    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    const int MAXN = 110;
    const int INFS = 0x3fffffff;
    int dp[25][MAXN][MAXN], N, E, D;
    
    int main() {
        while (~scanf("%d%d%d", &N, &E, &D)) {
            for (int i = 1; i <= N; i++)
                for (int d = 0; d <= D; d++) 
                    for (int e = 0; e <= E; e++)
                        dp[i][d][e] = INFS;
            dp[1][0][0] = 0;
            for (int i = 1; i <= N; i++) {
                for (int d = 1; d <= D; d++) {
                    for (int e = 1; e <= E; e++) {
                        for (int k = 1; k*k <= e && k <= d; k++) 
                            dp[i][d][e] = min(dp[i][d][e], dp[i][d-k][e-k*k] + 1);
                        dp[i+1][d][d] = min(dp[i+1][d][d], dp[i][d][e]);
                    }
                }
            }
            int ans = INFS;
            for (int e = 1; e <= E; e++)
                ans = min(ans, dp[N][D][e]);
            printf("%d\n", ans);
        }
        return 0;
    }

    代码2 (110ms) :

    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    const int MAXN = 110;
    const int INFS = 0x3fffffff;
    int dp[25][MAXN][MAXN], N, E, D;
    
    int main() {
        while (~scanf("%d%d%d", &N, &E, &D)) {
            for (int i = 1; i <= N; i++)
                for (int e = 0; e <= E; e++)
                    for (int d = 0; d <= D; d++)
                        dp[i][e][d] = INFS;
            dp[1][0][0] = 0;
            for (int i = 1; i <= N; i++) {
                for (int e = 1; e <= E; e++) {
                    for (int d = 1; d <= D; d++) {
                        for (int x = 1; ; x++) {
                            int coste = x * x, costd = x;
                            if (coste > e || costd > d) break;
                            for (int k = 1; k*coste <= e && k*costd <= d; k++)
                                dp[i][e][d] = min(dp[i][e][d], dp[i][e-coste*k][d-costd*k] + k);
                        }
                        dp[i+1][d][d] = min(dp[i+1][d][d], dp[i][e][d]);
                    }
                }
            }
            int ans = INFS;
            for (int i = 1; i <= N; i++)
                for (int e = 1; e <= E; e++)
                    ans = min(ans, dp[i][e][D]);
    
            printf("%d\n", ans);
        }
        return 0;
    }
     
    -------------------------------------------------------

    kedebug

    Department of Computer Science and Engineering,

    Shanghai Jiao Tong University

    E-mail: kedebug0@gmail.com

    GitHub: http://github.com/kedebug

    -------------------------------------------------------

  • 相关阅读:
    分页功能
    四个内置对象的作用范围
    include和application
    jsp中的session
    IDC机房的相关常识
    使用dm-cache组合SSD与HDD实现高性价比存储
    负载均衡基本原理与lvs
    秒级别执行脚本的方法
    Tomcat调优
    Nginx调优
  • 原文地址:https://www.cnblogs.com/kedebug/p/3006457.html
Copyright © 2020-2023  润新知