洛谷题目:P1233 [ICPC 2001 Taejon R] 木棍加工 题解(本题较难)

介绍:

前言:

本题求最少准备时间 ⇔ 求排序后宽度数组的最长严格上升子序列长度。以下是小亦的详细讲解⬇️

题目传送门:

https://www.luogu.com.cn/problem/P1233

#解题思路步骤:

1、明确问题规则与核心:

1.1、给定n根木棍,每根拥有长度l、宽度w,及其加工木棍存在准备的时间规则:第一根耗时了1分钟,如果后一根木棍长、宽均≤前一根,则无需额外准备,否则加1分钟的准备是假,并且要求求出加工全部木棍的最小总准备timing。

1.2、该题可以通过Dilworth定理转换成经典的最长上升至序列问题。具体:将木棍按照长度降序、同长度宽度降序并进行排序之后,最小准备时间等价于宽度序列的最长严格上升至序列长度。

1.3、本题不建议暴力枚举,若暴力枚举所有排序进行模拟加工,时间阶乘复杂度无法通过。

2、问题转化以及逻辑推导:

2.2、题目给的问题等价于:把所有木棍划分成尽可能少的递减序列。根据Dilworth定理,最少划分链的数量=最长反链长度。排序后反链对应宽度严格上升序列,因此只需求出宽度序列最长上升子序列长度即可。

3、动态dp状态设计:

我们仅需要一维dp数组去存储子问题答案,不需要复杂图结构:

3.1、doi:以排序后第i根木棍为结尾的最长严格上升宽度子序列长度。

3.2、答案:整个dp数组中的最大值,就是最少的准备时间。

##完成解题三步走:

小亦提供思维导图让大家更加清晰易懂!

###复杂度:

1、时间复杂度:

2、空间复杂度:

####代码:

cpp 复制代码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

struct stick1 {
    int l, w;
};

// 排序规则:长度降序,长度相等则宽度降序
bool cmp(const stick1 &a, const stick1 &b) {
    if (a.l != b.l)
        return a.l > b.l;
    return a.w > b.w;
}

int main() {
    int n;
    cin >> n;
    vector<stick1> stick2(n);
    for (int i = 0; i < n; ++i) {
        cin >> stick2[i].l >> stick2[i].w;
    }
    sort(stick2.begin(), stick2.end(), cmp);

    vector<int> w;
    for (auto &s : stick2) {
        w.push_back(s.w);
    }

    // 求最长上升子序列 LIS
    vector<int> dp(n, 1);
    int ans = 1;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < i; ++j) {
            if (w[j] < w[i]) {
                dp[i] = max(dp[i], dp[j] + 1);
            }
        }
        ans = max(ans, dp[i]);
    }
    cout << ans << endl;
    return 0;
}

--- 感谢观看---

制作:Code.小亦
代码提供:Code.小亦
题目思路部分提供:无

代码部分思路提供:无

知识共享:无

知识查找来源:无

初审:Code.小亦。

终审:Code.小亦。

本文章属于原创作品,禁止任何人进行转载,除合作之外!!

如在阅读中发现知识性错误、代码错误、错别字错误等情况私信博主或评论或通过邮箱2952104443@qq.com。

另:题目来源:首页 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

特:本文章/专栏在知乎网站合规授权发布。

相关推荐
青山木1 小时前
Hot 100 --- 电话号码的字母组合
java·数据结构·算法·leetcode·逻辑回归
闪电悠米2 小时前
力扣hot100-240.搜索二维矩阵2-单调性剪枝详解
数据结构·算法·leetcode·矩阵·哈希算法
imuliuliang2 小时前
关于基于图论的最短路径算法性能对比分析7
算法
SilentSlot2 小时前
【C/C++】手写 DPDK 协议栈(十二):TCP 并发与自实现 epoll 的就绪事件分发
c语言·c++·tcp/ip
SilentSlot2 小时前
【C/C++】手写 DPDK 协议栈(六):TCP 三次握手、状态机与数据回显
c语言·c++·tcp/ip
乱七八糟的屋子2 小时前
AMQP C++ 超详细实战教程(amqp-cpp 开源库从零入门到生产落地)
c++·rabbitmq·任务队列·amqp·流量削峰·c++服务端异步解耦·分布式消息通信
Escalating_xu2 小时前
C++11 彻底吃透 emplace_back 与 push_back(最全闭环:左右值|深浅拷贝|移动构造|万能引用|完美转发)
开发语言·c++
imuliuliang2 小时前
关于从栈与队列看算法思维的演化路径7
算法
春生野草2 小时前
个人笔记--大顶堆和基数排序
java·数据结构·算法