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
  • 相关阅读:
    【Java】XML编码
    【GIS】ArcGIS瓦片组织规则
    论写代码的合理性
    快速解决github网页图片显示不了的问题
    pyqt5-tools安装后 desinner.exe 报错 PyQt5 the application failed to start because no Qt platform could be initialized 最强大快速的解决
    Prometheus基本概述
    sql在group by 中使用case when
    【sql server自动化】sql server自动化备份
    (4.45)数据库编程中的三种性能模式比较
    【redis故障处理】redis哨兵节点之间无法互相识别通信
  • 原文地址:https://www.cnblogs.com/cherish-lin/p/11991879.html
Copyright © 2011-2022 走看看