zoukankan      html  css  js  c++  java
  • D

    There are nn people at the round gaming table. Each of them has a set of cards. Every card contains some number xx. Players make turns consecutively, one after another, starting from the player number 1. A player in his turn can either skip his turn (to pass), or put (and leave on the table) a card with a number that is strictly greater than the previously played last number. No more than kk players in a row can pass the turn. All players know the numbers written on the other players cards and always play optimally. Help gamblers to assemble an increasing sequence of maximum length.

    Input

    The first line contains two numbers nn and kk — the number of players and the maximum possible amount of turn skipping in a row.

    The next nn lines contain the description of the cards players have in their hands. The first number in the mimi is the number of cards the current player has in his hand. The following space separated miminumbers represent the written on the cards numbers xx.

    0mi1050≤∑mi≤105
    1n1051≤n≤105
    0k<n0≤k<n
    0x1090≤x≤109

    Output

    In the first line print the single number — the length of the maximum sequence. In the next lines print two space separated numbers: the player index number and the number written on the card he played. If several solutions exist, output any of them.

    Example

    Input
    3 1
    4 1 10 12 20
    2 11 21
    4 3 5 15 22
    
    Output
    9
    1 1
    3 3
    1 10
    2 11
    1 12
    3 15
    1 20
    2 21
    3 22

    #include <bits/stdc++.h>
    #define ll long long
    #define ull unsigned long long
    #define met(a, b) memset(a, b, sizeof(a))
    #define rep(i, a, b) for(int i = a; i <= b; i++)
    #define bep(i, a, b) for(int i = a; i >= b; i--)
    #define lowbit(x) (x&(-x))
    #define MID (l + r) / 2
    #define ls pos*2
    #define rs pos*2+1
    #define pb push_back
    #define ios() ios::sync_with_stdio(0)
     
    using namespace std;
    typedef pair<int,int>pi;
    const int maxn = 1e5 + 1010;
    const int inf = 0x3f3f3f3f;
    const ll INF = 0x3f3f3f3f3f3f3f3f;
    const ll mod = 1e9 + 7;
    
    struct node{
      int id,x;
      bool operator < (const node & w)const{
        return x < w.x || (x == w.x && id < w.id);
      }
    }arr[maxn];
    pi dp[maxn],tree[maxn<<2];
    void pushup(int rt){
      tree[rt] = max(tree[rt*2],tree[rt*2+1]);
    }
    void build(int l,int r,int rt){
      if(l == r){
        tree[rt] = pi(0,-1);
        return ;
      }
      int mid = (l + r) / 2;
      build(l,mid,rt*2);
      build(mid + 1,r,rt*2+1);
      pushup(rt);
    }
    pi query(int L,int R,int l,int r,int rt){//询问[L,R]内长度最长的上升子序列节点
      if(L > R)return pi(0,-1);
      if(L <= l && r <= R){
        return tree[rt];
      }
      int mid = (l + r) / 2;
      pi ans = pi(0,-1);
      if(L <= mid)ans = max(ans,query(L,R,l,mid,rt*2));
      if(R >  mid)ans = max(ans,query(L,R,mid+1,r,rt*2+1));
      return ans;
    }
    void update(int pos,pi val,int l,int r,int rt){//pos位置更改最优值(和自身取最优值)
      if(l == r){
        tree[rt] = max(tree[rt],val);
        return ;
      }
      int mid = (l + r) / 2;
      if(pos <= mid)update(pos,val,l,mid,rt*2);
      else update(pos,val,mid+1,r,rt*2+1);
      pushup(rt);
    }
    void dfs(int u,int dep){//dfs寻找路径,dp[u].second 代表下一个下标是几
      if(u == -1){
        cout << dep << endl;
        return ;
      }
      dfs(dp[u].second,dep+1);
      cout << arr[u].id << ' ' << arr[u].x << endl;
    }
    int main()
    {
      int n,k,top = 0;
      cin >> n >> k;
      build(1,n,1);
      rep(i,1,n){
        int m;
        cin >> m;
        rep(j,1,m){
          int x;
          cin >> x;
          arr[++top] = (node){i,x};
        }
      }
      sort(arr+1,arr+1+top);
      int i;
      for(i = 1;i <= top;){
        for(int j = i;j <= top;j++){//一个值的数据有多个的话,处理完,先不更新,因为题目保证严格递增
          if(arr[i].x != arr[j].x)break;
          int id = arr[j].id;
          int pos = ((id - k - 2) % n + n) % n + 1;//最多可跳过k个,这个推一下就好了~
          if(pos < id)dp[j] = query(pos,id-1,1,n,1);
          else dp[j] = max(query(pos,n,1,n,1),query(1,id-1,1,n,1)); 
        }
        int j;
        for(j = i;j <= top;j++){
          if(arr[i].x != arr[j].x)break;
          if(dp[j].first == 0 && arr[j].id > k + 1)continue;//第一个人特判
          dp[j].first++;//以j为结尾的最长上升子序列加1
          int pos = arr[j].id;
          update(pos,pi(dp[j].first,j),1,n,1);//更新最优值
        }
        i = j;
      }
      int ans = 0,rt = 0;
      for(int i = 1;i <= top;i++){
        if(dp[i].first > ans){
          ans = dp[i].first;
          rt = i;
        }
      }
      if(rt == 0)cout << 0 << endl;
      else dfs(rt,0);
      return 0;
    }
    /*
    3 0
    3 1 2 3
    3 1 2 1
    4 1 2 3 2
    */
    View Code
  • 相关阅读:
    C盘与D盘中间有个恢复分区,导致C盘不能扩展卷解决
    Win下,QT控制台无输出解决
    QT与ECharts交互,绘制曲线图
    博客园好看的自定义主题
    Qt5之控件在初始化时就触发了槽函数的问题解决方案
    使用QCustomPlot,跟随鼠标动态显示线上点的值
    QCustomPlot下setTickLabelType()函数在新版本被移除如何解决
    记一次QT使用QAxWidget打开.html文件调用显示离线百度地图不能缩放,自定义图片不能显示解决方法
    使用QPainter绘制汽车仪表盘,动态显示
    QT下使用百度地图js,发送角度值给js使小车根据角度值调整车头方向
  • 原文地址:https://www.cnblogs.com/cherish-lin/p/11991879.html
Copyright © 2011-2022 走看看