• D. Unmerge


    D - Unmerge

    https://codeforces.com/contest/1382/problem/D
    这个题目学到了 ,巧妙的用01背包dp解决问题
    1. 用两个数组合并,可以发现,如果有一段a[l.....r] 小于b[i] , 那么肯定是先拿a[l.....r],尽管这一段a[l.....r]里面的顺序我们不知道,最坏的就是波峰,一会变大,一会变小,但是他和b的关系是确定的,b[i] >= max(a[l......r]),反过来b[x.....y]对a[i],也是这样的关系
    2. 例如3 , 1 , 4 ,5 , 2 , 6
    3. 这个例子被分为(3 , 1) , (4) , (5 , 2) ,(6)
    4. 这个是最坏最坏情况下的分法,那么对于一个长度位n的数组,它会被其中x段组成,每段都可选可不选,就是dp了 ,还是01背包,每个只能选一次,容量是每段的大小,价值也是每段大小,dp[n] 最大结果要是n

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <unordered_map>
    #include <vector>
    #include <map>
    #include <list>
    #include <queue>
    #include <cstring>
    #include <cstdlib>
    #include <ctime>
    #include <cmath>
    #include <stack>
    #include <set>
    #pragma GCC optimize(3 , "Ofast" , "inline")
    using namespace std ;
    #define ios ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0)
    #define x first
    #define y second
    #define ls rt << 1
    #define rs rt << 1 | 1
    typedef long long ll ;
    const double esp = 1e-6 , pi = acos(-1) ;
    typedef pair<int , int> PII ;
    const int N = 1e6 + 10 , INF = 0x3f3f3f3f , mod = 1e9 + 7;
    int cinint(){  int t ; scanf("%d" , &t) ;  return t ;}
    int cinll(){ll t ;scanf("%lld" , &t) ;return t ;}
    int a[N] , b[N] , dp[N] ;
    int work()
    {
      int n = cinint() ;
      int maxn = 0 ;
      vector<int> ans ;
      for(int i = 1; i <= 2 * n ;i ++ )
      {
         a[i] = cinint() ;
         if(maxn <= a[i])
          maxn = a[i] , ans.push_back(i) ;
      }
      ans.push_back(2 * n + 1) ;
      int cnt = 0 ;
      for(int i = 1; i < ans.size() ;i ++ ) b[++ cnt] = ans[i] - ans[i - 1] ;
      for(int i = 0 ;i <= n ;i ++ ) dp[i] = -INF ;
      dp[0] = 0 ;
      for(int i = 1 ;i <= cnt ;i ++ ) {
        for(int j = n ;j >= b[i] ;j --) {
          dp[j] = max(dp[j] , dp[j - b[i]] + b[i]) ;
        }
      }
      printf("%s
    " , dp[n] == n ? "YES" : "NO") ;
      return 0 ;
    }
    int main()
    {
      int t = cinint() ;
      while(t --)
      work() ;
      return 0 ;
    }
    /*
    */
    
    
  • 相关阅读:
    JS函数强化
    Javascript创建对象的方式
    call和apply的区别
    事件绑定和普通事件有什么区别
    又走一个
    风的季节
    关于Dictionary的线程安全问题
    进程管理简述
    开通
    WPF 音乐播放器界面
  • 原文地址:https://www.cnblogs.com/spnooyseed/p/13359592.html
Copyright © 2020-2023  润新知