Leetcode c++ 1114. 按序打印 1114. Print in Order

本文探讨了C++中实现线程同步的多种方法,包括使用计数变量、future和promise、互斥量、unique_lock和lock_guard等,以确保线程按特定顺序执行。

1114. 按序打印
我们提供了一个类:

public class Foo {
public void one() { print(“one”); }
public void two() { print(“two”); }
public void three() { print(“three”); }
}
三个不同的线程将会共用一个 Foo 实例。

线程 A 将会调用 one() 方法
线程 B 将会调用 two() 方法
线程 C 将会调用 three() 方法
请设计修改程序,以确保 two() 方法在 one() 方法之后被执行,three() 方法在 two() 方法之后被执行。

示例 1:

输入: [1,2,3]
输出: “onetwothree”
解释:
有三个线程会被异步启动。
输入 [1,2,3] 表示线程 A 将会调用 one() 方法,线程 B 将会调用 two() 方法,线程 C 将会调用 three() 方法。
正确的输出是 “onetwothree”。
示例 2:

输入: [1,3,2]
输出: “onetwothree”
解释:
输入 [1,3,2] 表示线程 A 将会调用 one() 方法,线程 B 将会调用 three() 方法,线程 C 将会调用 two() 方法。
正确的输出是 “onetwothree”。

没有接触过多线程编程的我写的代码,提交了两次才通过,第一次甚至超时:

class Foo {
public:
    Foo() {
        
    }
    int count=0;
    void first(function<void()> printFirst) {
        // printFirst() outputs "first". Do not change or remove this line.
        printFirst();
        count=1;
    }

    void second(function<void()> printSecond) {
        while(count<=0){
            
        }
        // printSecond() outputs "second". Do not change or remove this line.
        printSecond();
        count=2;
    }

    void third(function<void()> printThird) {
        while(count<=1){
            
        }
        // printThird() outputs "third". Do not change or remove this line.
        printThird();
    }
};

其他方法,一些新东西

  1. future 头文件和promise
#include <future>

class Foo {
public:
    promise<void> p1, p2;
    
    Foo() {
        
    }

    void first(function<void()> printFirst) {
        
        // printFirst() outputs "first". Do not change or remove this line.
        printFirst();
        p1.set_value(); // 为p1赋值
    }

    void second(function<void()> printSecond) {
        p1.get_future().wait(); // 等待p1
        // printSecond() outputs "second". Do not change or remove this line.
        printSecond();
        p2.set_value(); // 为p2赋值
    }

    void third(function<void()> printThird) {
        p2.get_future().wait(); // 等待p2
        // printThird() outputs "third". Do not change or remove this line.
        printThird();
    }
};

  1. C++互斥量pthread_mutex_t
class Foo {
public:
    pthread_mutex_t one;
    pthread_mutex_t two;
    Foo() {
        pthread_mutex_init(&one, NULL);
        pthread_mutex_init(&two, NULL);
        pthread_mutex_lock(&one);
        pthread_mutex_lock(&two);
    }

    void first(function<void()> printFirst) {
        
        // printFirst() outputs "first". Do not change or remove this line.
        printFirst();
        pthread_mutex_unlock(&one);
    }

    void second(function<void()> printSecond) {
        
        // printSecond() outputs "second". Do not change or remove this line.
        pthread_mutex_lock(&one);
        printSecond();
        pthread_mutex_unlock(&one);
        pthread_mutex_unlock(&two);
    }

    void third(function<void()> printThird) {
        
        // printThird() outputs "third". Do not change or remove this line.
        pthread_mutex_lock(&two);
        printThird();
        pthread_mutex_unlock(&two);
    }
};

3.C++ 并发编程,std::unique_lock与std::lock_guard

class Foo {
public:
    Foo() {
        
    }

    void first(function<void()> printFirst) {
        // 等待直至 main() 发送数据
	    std::unique_lock<std::mutex> lk(g_mutex);  
        // printFirst() outputs "first". Do not change or remove this line.
        printFirst();
        // 通知前完成手动解锁,以避免等待线程才被唤醒就阻塞(细节见 notify_one )
        counter++;
        cv1.notify_one();
    }

    void second(function<void()> printSecond) {
	    std::unique_lock<std::mutex> lk(g_mutex);
        cv1.wait(lk, [this](){return counter == 2;}); // 阻塞当前线程,直到条件变量被唤醒 
        // printSecond() outputs "second". Do not change or remove this line.
        printSecond();
        counter++;
        cv2.notify_one();
    }

    void third(function<void()> printThird) {
        
	    std::unique_lock<std::mutex> lk(g_mutex);
        cv2.wait(lk, [this](){return counter == 3;});
        // printThird() outputs "third". Do not change or remove this line.
        printThird();
    }
    
private:
    int counter = 1;
    std::condition_variable cv1;
    std::condition_variable cv2;
    // 使用lock和unlock手动加锁
    std::mutex g_mutex;
};

4.还有mutex 等,互斥变量。。还蛮多的

B. Array Recoloring time limit per test2 seconds memory limit per test256 megabytes You are given an integer array a of size n . Initially, all elements of the array are colored red. You have to choose exactly k elements of the array and paint them blue. Then, while there is at least one red element, you have to select any red element with a blue neighbor and make it blue. The cost of painting the array is defined as the sum of the first k chosen elements and the last painted element. Your task is to calculate the maximum possible cost of painting for the given array. Input The first line contains a single integer t (1≤t≤103 ) — the number of test cases. The first line of each test case contains two integers n and k (2≤n≤5000 ; 1≤k<n ). The second line contains n integers a1,a2,…,an (1≤ai≤109 ). Additional constraint on the input: the sum of n over all test cases doesn't exceed 5000 . Output For each test case, print a single integer — the maximum possible cost of painting for the given array. Example InputCopy 3 3 1 1 2 3 5 2 4 2 3 1 3 4 3 2 2 2 2 OutputCopy 5 10 8 Note In the first example, you can initially color the 2 -nd element, and then color the elements in the order 1,3 . Then the cost of painting is equal to 2+3=5 . In the second example, you can initially color the elements 1 and 5 , and then color the elements in the order 2,4,3 . Then the cost of painting is equal to 4+3+3=10 . In the third example, you can initially color the elements 2,3,4 , and then color the 1 -st element. Then the cost of painting is equal to 2+2+2+2=8 . 用cpp解决
最新发布
03-19
<think>好的,我现在需要帮助用户解决如何使用C++实现数组重着色问题的最大涂色成本计算。首先,我需要理解用户的需求。用户提到了“Array Recoloring”,也就是数组重新着色,可能涉及改变数组元素的颜色以使某些条件满足,同时计算最大成本。根据用户提供的引用[1],他们可能参考了一篇关于图像重新染色的论文,但具体代码没有公开,所以用户想自己实现。 接下来,我需要确定“最大涂色成本”具体指什么。通常,这类问题可能涉及在满足特定约束下,通过改变元素颜色使得总成本最大。例如,每次改变颜色可能需要一定的成本,或者在相邻元素颜色不同的情况下获得奖励。不过,用户没有给出具体定义,可能需要假设或参考常见问题。 查看用户提供的引用[2],有一个公式:$a[i][j] = (\sum_{x=i}^n \sum_{y=j}^m d[i][j]) \bmod 2$。这可能与二维数组的处理有关,但不确定是否直接相关。引用[3]提到高斯核和距离,可能与颜色相似性有关,但暂时可能不适用。 假设问题的大致结构是:给定一个数组,每个元素有一个颜色,可以重新着色,每次改变颜色有成本,目标是在预算内最大化某种收益,或者直接最大化总收益。或者,可能是相邻元素颜色不同时获得收益,需要安排颜色使得总收益最大。 但用户明确提到“最大涂色成本计算”,可能是指每次重新着色需要成本,而总成本是各次改变的总和,但需要最大化这个成本?这似乎不太合理,通常成本可能需要最小化。或者可能涂色本身有收益,比如不同颜色对应不同收益,选择颜色使得总收益最大。因此,可能需要更明确的问题定义。 由于用户没有给出具体的问题描述,可能需要参考常见的数组重着色问题。例如,LeetCode上有一道题目叫做“Minimum Operations to Make Array Continuous”(但这是关于连续数组的最小操作),或者“Paint House”问题,其中涂色有成本,要求相邻颜色不同,求最小成本。但用户需要的是最大涂色成本,可能与这类问题相反。 另一种可能是,每个元素可以涂成不同的颜色,每次涂色有成本,而目标是在允许的操作次数内最大化总成本。或者,当相邻元素颜色不同时,获得更高的成本。这里可能需要进一步假设。 假设问题类似如下:给定一个数组,每个元素初始颜色,可以重新着色为其他颜色,每次改变颜色有特定的成本(可能与新旧颜色有关),求在允许的操作下,如何选择颜色使得总成本最大。但通常这类问题要求最小化成本,所以可能用户的问题有特殊定义。 或者,问题可能类似于:每次改变颜色需要一定的成本,而总预算是固定的,求在预算内可以改变颜色后的数组中,使得某种美观度(例如相邻不同颜色的数量)最大。这种情况下,最大涂色成本可能指在预算内能达到的最大美观度。 由于用户的信息有限,可能需要基于常见问题给出一个可能的解决方案。例如,动态规划处理相邻元素的颜色选择,以最大化某种得分。或者贪心算法。 参考用户提供的引用[2]中的公式,可能涉及二维数组的处理,使用前缀和或某种模运算。例如,计算某个区域的和,然后取模决定颜色。但不确定是否直接相关。 考虑到用户希望用C++实现,需要给出具体的代码结构。例如,可能的动态规划方法,或者遍历所有可能的涂色方式,计算成本。 假设问题类似于:给定一个数组,每个元素可以涂成k种颜色,每次涂色成本为某个值,求涂色后的数组满足相邻元素颜色不同的情况下,总涂色成本最大。或者,每个颜色有不同的收益,相邻颜色不同的情况下,总收益最大。 例如,动态规划方法,其中dp[i][c]表示前i个元素,第i个元素颜色为c时的最大总成本。转移方程可能为dp[i][c] = max(dp[i-1][d] + cost(c)),其中d != c。这类似于“Paint House”问题,但求最大值。 假设问题为此,接下来需要编写C++代码。例如,给定颜色种类k,每个元素涂成颜色c的成本为cost[i][c],求最大总成本使得相邻颜色不同。 代码的大致步骤: 1. 读取输入,包括数组长度n,颜色种类k,每个元素各颜色的涂色成本。 2. 初始化动态规划数组,dp[i][c]表示第i个元素涂颜色c时的最大总成本。 3. 对于每个元素i,遍历所有可能的颜色c,找到前一个元素颜色d不等于c时的最大dp[i-1][d],加上当前cost[i][c]。 4. 最终结果就是最后一个元素所有颜色中的最大值。 例如,代码可能如下: ```cpp #include <iostream> #include <vector> #include <algorithm> using namespace std; int main() { int n, k; cin >> n >> k; vector<vector<int>> cost(n, vector<int>(k)); for (int i = 0; i < n; ++i) { for (int j = 0; j < k; ++j) { cin >> cost[i][j]; } } vector<vector<int>> dp(n, vector<int>(k, 0)); // 初始化第一个元素 for (int c = 0; c < k; ++c) { dp[0][c] = cost[0][c]; } for (int i = 1; i < n; ++i) { for (int c = 0; c < k; ++c) { int max_prev = 0; for (int d = 0; d < k; ++d) { if (d != c) { max_prev = max(max_prev, dp[i-1][d]); } } dp[i][c] = max_prev + cost[i][c]; } } int result = 0; for (int c = 0; c < k; ++c) { result = max(result, dp[n-1][c]); } cout << result << endl; return 0; } ``` 这段代码处理每个元素选择不同颜色,且相邻颜色不同的情况下,求最大总成本。假设每个颜色的成本是给定的,比如cost[i][c]表示将第i个元素涂成颜色c的成本。这可能符合用户的问题描述。 不过,用户的问题是否如此还需要确认。例如,如果问题中的成本是改变颜色所需的代价,而初始颜色已存在,那么可能需要计算是否需要改变颜色,以及改变后的成本。例如,初始颜色数组为colors,可以改变某些元素的颜色到其他颜色,每次改变需要一定的成本,总预算是B,求在预算内改变颜色后的数组中,相邻不同颜色的对数最多。此时问题转化为在预算限制下的优化问题,可能更复杂,需要使用动态规划或其他方法。 但根据用户提供的引用[2]中的公式,可能涉及二维数组和模运算,可能与位操作相关,但不确定。可能需要更详细的问题描述。不过由于用户没有提供具体的问题定义,只能根据常见情况假设。 综上,可能需要基于动态规划的方法,处理相邻颜色不同的约束,并计算最大总成本。代码结构如上,可能满足用户的需求。</think>要解决数组重着色问题中的最大涂色成本计算,可以采用动态规划方法。假设每个元素可涂$k$种颜色,相邻元素颜色不同时获得对应成本,目标是找到涂色方案使得总成本最大。 ### 实现步骤 1. **输入处理**:读取数组长度$n$和颜色种类$k$,以及每个位置各颜色的涂色成本。 2. **动态规划定义**:设$dp[i][c]$表示第$i$个元素涂颜色$c$时的最大累计成本。 3. **状态转移**:对每个位置$i$,遍历所有可能的颜色$c$,从前一位置的非$c$颜色中选择最大值进行累加。 4. **结果提取**:最终结果为最后一个元素所有颜色状态的最大值。 ### C++代码实现 ```cpp #include <iostream> #include <vector> #include <algorithm> using namespace std; int main() { int n, k; cin >> n >> k; vector<vector<int>> cost(n, vector<int>(k)); for (int i = 0; i < n; ++i) for (int j = 0; j < k; ++j) cin >> cost[i][j]; vector<vector<int>> dp(n, vector<int>(k, 0)); // 初始化第一个元素的成本 for (int c = 0; c < k; ++c) dp[0][c] = cost[0][c]; for (int i = 1; i < n; ++i) for (int c = 0; c < k; ++c) { int max_prev = 0; for (int d = 0; d < k; ++d) if (d != c) max_prev = max(max_prev, dp[i-1][d]); dp[i][c] = max_prev + cost[i][c]; } cout << *max_element(dp[n-1].begin(), dp[n-1].end()); return 0; } ``` ### 代码说明 - **时间复杂度**:$O(nk^2)$,适用于$k$较小的场景。 - **空间优化**:可用滚动数组将空间复杂度从$O(nk)$优化到$O(k)$[^2]。 - **关键点**:通过动态规划确保相邻颜色不同,并始终选择前一位置的最大有效成本。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值