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;
    }
  • 相关阅读:
    401. Binary Watch
    46. Permutations
    61. Rotate List
    142. Linked List Cycle II
    86. Partition List
    234. Palindrome Linked List
    19. Remove Nth Node From End of List
    141. Linked List Cycle
    524. Longest Word in Dictionary through Deleting
    android ListView详解
  • 原文地址:https://www.cnblogs.com/zzzzzzy/p/13358914.html
Copyright © 2011-2022 走看看