• POJ 3253 Fence Repair 题解 《挑战程序设计竞赛》


    题目:POJ - 3253

    书中例题。

    在看题解之前自己做了一下,用了错误的贪心策略:“越短的木棒切割的时间应该越晚”,局部来看是对的。

    正确策略的局部也是这样的。

    不过自己的想法不够全面,只想到了第一步。

    例如需要1,2,3,4,5 五根木棒,我觉得应该:

    先花15的代价切下来长度为5的,

    再花10的代价切下来长度为4的,

    再花6的代价切下来长度为3的,

    最后花3的代价切下来长度为2的,

    剩下的也就是长度为1的。

    这样代价一共是15+10+6+3=34,而最优策略代价为33.

    因此, 虽然说越长的木棒应该最先被切没错,但是对于选择最长木棒这件事,并不是直接从题目所需要的所有长度的木棒里面选最长的,而是:两根次长的也许可以拼成一根比当前最长更长的。

    因此应该从小往大遍历,不断选取最短的两根木棒组成新木棒加入所需队列中,换个角度就是说:最短的木棒与次短的木棒应该是兄弟节点。

    仔细领会错误和正确策略的区别(懒得开Visio了✧(≖ ◡ ≖✿)):

    1+2拼成3,3+3拼成6,此时需要6、5、4三根木棒,6便是最大的,而不是从一开始受限的角度所得出的5。

    代码:

     1 #include <iostream>
     2 #include <algorithm>
     3 
     4 using namespace std;
     5 
     6 int n;
     7 int plank[20000];
     8 
     9 void slove() {
    10     long long res = 0;
    11     
    12     while (n > 1) {
    13         int min = 0;        //最小的板的下标 
    14         int minNext = 1;    //次小的板的下标 
    15         
    16         if (plank[min] > plank[minNext]) {
    17             swap(min, minNext);
    18         }
    19         
    20         for (int i = 2; i < n; i++) {           //找到最小和次小的两块板 
    21             if (plank[i] < plank[min]) {
    22                 minNext = min;
    23                 min = i;
    24             }
    25             else if (plank[i] < plank[minNext]) {
    26                 minNext = i;
    27             }
    28         }
    29         
    30         int t = plank[min] + plank[minNext];
    31         res += t;
    32                 
    33         if (min == n - 1) {                //将拼合后的板加入到数组中,去掉原来的 
    34             swap(min, minNext); 
    35         }
    36         plank[min] = t;
    37         plank[minNext] = plank[n - 1];
    38         
    39         n--;         
    40     }
    41     cout << res << endl;
    42 }
    43 
    44 int main() {
    45     cin >> n;
    46     for (int i = 0; i < n; i++) {
    47         cin >> plank[i];
    48     }
    49     slove();
    50     
    51     return 0;    
    52 }
  • 相关阅读:
    I帧/P帧/B帧---术语解释
    利用forwardInvocation实现消息重定向
    doubango地址配置
    ARC使用小结
    NSException异常处理
    Runtime of Objective-C
    perl脚本框架整理
    模块——Getopt::Long接收客户命令行参数和Smart::Comments输出获得的命令行参数内容
    Linux学习进阶示意图
    Linux——入门命令
  • 原文地址:https://www.cnblogs.com/carolunar/p/6378687.html
Copyright © 2020-2023  润新知