zoukankan      html  css  js  c++  java
  • Codeforces Round #658 (Div. 2)

    题目链接:Unmerge

    题意:定义两个数组的合并merge(a,b),每次将数组a第一个元素和数组b第一个元素中最小的那个放到数组c中,同时删除那个最小的元素,现在给你一个长度为2*n的排列,问是否能由两个长度为n的数组合并而成

    思路:对于长度为2*n的排列,显然是通过一段一段合并得到的,例如(3,2,6,1,5,7,8,4),找到3后面比他大的第一个数6,6后面比他大的第一个数7,7后面比他大的第一个数8,应该分为(3,2),(6,1,5),(7),(8,4)这四段,然后将这四段进行分配,判断能够组成两个长度为n的数组,用01背包判断(背包容量为n,物品的容量和价值都为每一段的长度),判断最后的最大价值是否为n即可

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <vector>
     
    using namespace std;
     
    typedef long long ll;
     
    const int N = 4010;
    const int INF = 0x3f3f3f3f;
     
    int T, n, cnt, a[N], d[N], dp[N];
    vector<int> p;
     
    int main()
    {
        // freopen("in.txt", "r", stdin);
        // freopen("out.txt", "w", stdout);
        scanf("%d", &T);
        while (T--) {
            cnt = 0;
            p.clear();
            scanf("%d", &n);
            for (int i = 1; i <= 2 * n; i++) scanf("%d", &a[i]);
            int imax = 0;
            for (int i = 1; i <= 2 * n; i++) {
                if (a[i] < imax) continue;
                imax = a[i];
                p.push_back(i);
            }
            p.push_back(2 * n + 1);
            for (int i = 1; i < p.size(); i++)
                d[++cnt] = p[i] - p[i - 1];
            for (int i = 1; i <= n; i++) dp[i] = -INF;
            for (int i = 1; i <= cnt; i++)
                for (int k = n; k >= d[i]; k--)
                    dp[k] = max(dp[k], dp[k - d[i]] + d[i]);
            printf(n == dp[n] ? "YES
    " : "NO
    ");
        }
        return 0;
    }
  • 相关阅读:
    【BZOJ2243】【SDOI2011】染色 (LCT)
    【BZOJ2631】tree (LCT)
    【BZOJ3626】【LNOI2014】LCA (树剖+离线)
    [BZOJ3244][NOI2013] 树的计数
    BZOJ2754 SCOI2012day1T2喵星球上的点名(后缀数组)
    BZOJ2753 SCOI2012day1T1滑雪与时间胶囊(bfs+kruskal)
    Swift
    Library not loaded: @rpath/libswiftCore.dylib
    PHP require include 区别
    Mac OS 下 eclipse中文乱码解决方法
  • 原文地址:https://www.cnblogs.com/zzzzzzy/p/13358914.html
Copyright © 2011-2022 走看看