美文网首页
C++实现合唱队问题

C++实现合唱队问题

作者: Virtualer | 来源:发表于2019-09-25 13:57 被阅读0次

    题目:
    计算最少出列多少位同学,使得剩下的同学排成合唱队形

    说明:
    N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形。
    合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2…,K,他们的身高分别为T1,T2,…,TK, 则他们的身高满足存在i(1<=i<=K)使得T1<T2<......<Ti-1<Ti>Ti+1>......>TK。
    你的任务是,已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。

    输入:

    8
    186 186 150 200 160 130 197 200

    输出:

    4

    两遍最长递增子序列,第一遍从左往右,第二遍从右往左,然后把两遍动态规划的结果相加,取最大的那个,比如8 186 186 150 200 160 130 197 200,第一遍dp的结果是 1 1 1 2 2 1 3 4,第二遍dp的结果为3 3 2 3 2 1 1 1,那么相加最大是5,所以需要出列的同学个数就是8-5+1=4.代码如下:

    #include <iostream>
    #include <vector>
    #include <algorithm>
    using namespace std;
     
    // 基本思路,两遍最长递增子序列,并找和最大
    int main(void)
    {
        int n;
        while (cin >> n)
        {
            int tmp;
            vector<int> queue;
            vector<int> dp_1(n, 1);
            vector<int> dp_2(n, 1);
             
            for (int i = 0; i < n; ++i)
            {
                cin >> tmp;
                queue.push_back(tmp);
            }
     
            // 第一遍dp
            for (int i = 0; i < n; ++i)
            {
                for (int j = i - 1; j >= 0; --j)
                {
                    if (queue[i] > queue[j] && dp_1[i] < dp_1[j] + 1)
                        dp_1[i] = dp_1[j] + 1;
                }
            }
     
            std::reverse(queue.begin(), queue.end());
            // 第二遍dp
            for (int i = 0; i < n; ++i)
            {
                for (int j = i - 1; j >= 0; --j)
                {
                    if (queue[i] > queue[j] && dp_2[i] < dp_2[j] + 1)
                        dp_2[i] = dp_2[j] + 1;
                }
            }
            std::reverse(dp_2.begin(), dp_2.end());
     
            int max = -1;
            int sum;
            for (int i = 0; i < n; ++i)
            {
                sum = dp_1[i] + dp_2[i];
                if (sum > max)
                {
                    max = sum;
                }
            }
            cout << n - max + 1 << endl;
        }
        return 0;
    }
    

    求最长子序列理解
    说实话这个题是我没看懂的,先放着慢慢理解吧。

    相关文章

      网友评论

          本文标题:C++实现合唱队问题

          本文链接:https://www.haomeiwen.com/subject/vzmmyctx.html