zoukankan      html  css  js  c++  java
  • Codeforces 1381B Unmerge(序列划分+背包)

    题意:给出一个长度为2*n的序列p(1-2*n的整数组成)问是否能由长度为n的a,b数组通过merge(a,b)构成数组p,merge是双指针放在a,b数组起点中,每次取出a[i], b[j]小的,对应指针右移,直到取完。n<2e3

    题解:每次都是取出较小的,尝试通过以p【1】的递增序列对p序列划分,例如 3 2 6 1 5 7 8 4划分为【3 2】【6 1 5】 【7】【8 4】,划分为一组的表示该组的数字的必然是在a中,或者b中,则该题可以转化成从这些组中能否取出一些组并且使得这些组的数字有n个,直接跑背包判断可行性即可。

    #include <bits/stdc++.h>
    #define IO_read ios::sync_with_stdio(false);cin.tie(0)
    #define fre freopen("C:\in.txt", "r", stdin)
    #define _for(i,a,b) for(int i=a; i< b; i++)
    #define _rep(i,a,b) for(int i=a; i<=b; i++)
    #define inf 0x3f3f3f3f
    #define lowbit(a) ((a)&-(a))
    using namespace std;
    typedef long long ll;
    template <class T>
    void read(T &x)
    {
        char c; bool op=0;
        while(c=getchar(), c<'0'||c>'9') if(c=='-') op=1;
        x=c-'0';
        while(c=getchar(), c>='0'&&c<='9') x=x*10+c-'0';
        if(op) x=-x;
    }
    
    const int maxn=5e3+5;
    int T, n, f[maxn], a[maxn], v[maxn];
    
    int main()
    {
        //fre;
        read(T);
        while(T--)
        {
            read(n);
            _rep(i, 1, 2*n) read(a[i]);
            int p=1, cnt=0;
            while(p<=2*n)
            {
                int len=1, tmax=a[p++];
                while(p<=2*n && tmax>a[p]) p++, len++;
                v[++cnt]=len;
            }
            //for(int i=1; i<=cnt; i++) printf("%d ", v[i]);
            for(int i=1; i<=n; i++) f[i]=-inf;
            for(int i=1; i<=cnt; i++)
                for(int j=n; j>=v[i]; j--)
                    f[j]=max(f[j], f[j-v[i]]+v[i]);
            printf(f[n]==n? "YES
    ":"NO
    ");
        }
        return 0;
    }
  • 相关阅读:
    C#24种设计模式汇总
    传智播客C++视频学习笔记(5)
    传智播客C++视频学习笔记(3)
    传智播客C++视频学习笔记(1)
    Learning hard 网络编程
    Learning hard 学习笔记
    男人和女人 访问者模式
    其实你不懂老板的心 解释器模式
    项目多也别傻做 享元模式
    git常用命令
  • 原文地址:https://www.cnblogs.com/Yokel062/p/13434431.html
Copyright © 2011-2022 走看看