• XHXJ's LIS HDU


    代码+题解:

      1 //题意:
      2 //输出在区间[li,ri]中有多少个数是满足这个要求的:这个数的最长递增序列长度等于k
      3 //注意是最长序列,可不是子串。子序列是不用紧挨着的
      4 //
      5 //题解:
      6 //很明显前面最长递增序列的长度会影响到后面判断,而且还要注意我们要采用哪种求最长递增序列的方式(一共有两种,
      7 //一种复杂度为nlog(n),另一种是n^2),这里我才采用的是nlog(n)的。
      8 //
      9 //算法思想:
     10 //定义d[k]:
     11 //长度为k的上升子序列的最末元素,若有多个长度为k的上升子序列,则记录最小的那个最末元素。
     12 //定义a[]:a数组放置的是我们要处理的元素
     13 //首先len = 1,d[1] = a[1],然后对a[i]:若a[i]>d[len],那么len++,d[len] = a[i];
     14 //否则,我们要从d[1]到d[len-1]中找到一个j,满足d[j-1]<a[i]<d[j],则根据D的定义,我们需要更新长度为j的上升子序列的最末元素(使之为最小的)
     15 //即 d[j] = a[i];最终答案就是len
     16 //
     17 //代码:
     18 //d[1] = a[1];
     19 //len=1;
     20 //for(i=2; i<=p; ++i)
     21 //{
     22 //    if(a[i]>d[len])
     23 //        d[++len]=a[i];
     24 //    else
     25 //    {
     26 //        int pos=binary_search(i);   // 如果用STL: pos=lower_bound(d,d+len,a[i])-d;
     27 //        d[pos] = a[i];
     28 //    }
     29 //    printf("%d
    ",len);
     30 //}
     31 //
     32 //结果:
     33 //这个d数组里面放置得结果可能不是正确最长递增序列对应的一个序列,它的长度是可以保证是正确的,但是序列本身不一定
     34 //
     35 //回归原题:
     36 //本体就采用这一种方法来获取最长递增序列,每一个位置都对应一个最长递增序列(虽然这个序列本身不一定对,但是它可以
     37 //当作一个状态)
     38 //比如一个递增序列为0 1 3 4那么就把它压缩成二进制的每一位,即2^0+2^1+2^3+2^4,这个结果就是我们的状态,这个样子
     39 //我们就把0、1、2、3、4、5、6、7、8、9这些状态压缩成了一个值。
     40 //然后就写出来了。。。。
     41 
     42 #include<stdio.h>
     43 #include<string.h>
     44 #include<algorithm>
     45 #include<iostream>
     46     using namespace std;
     47     const int maxn=20;
     48     const int N=1<<10;
     49     typedef long long ll;
     50     ll v[maxn],dp[maxn][N][20],w[15],k;
     51     ll update(ll x,ll y) //更新我们压缩的状态
     52     {
     53         for(ll i=x; i<10; ++i)
     54         {
     55             if(y&(1<<i)) return ((y^(1<<i))|(1<<x));
     56         }
     57         return y|(1<<x);
     58     }
     59     ll get_num(ll x)
     60     {
     61         ll ans=0;
     62         while(x)
     63         {
     64             if(x&1) ans++;
     65             x>>=1;
     66         }
     67         return ans;
     68     }
     69     ll dfs(ll pos,ll sta,bool limit,bool lead)
     70     {
     71         if(get_num(sta)>k) return 0;
     72         if(pos==-1)
     73         {
     74             if(get_num(sta)==k)
     75                 return 1;
     76             else return 0;
     77         }
     78         if(!limit && dp[pos][sta][k]!=-1) return dp[pos][sta][k];
     79         ll up=limit?v[pos]:9;
     80         ll tmp=0;
     81         for(ll i=0; i<=up; ++i)
     82         {
     83             //这一行可以代替下面的
     84             //tmp+=dfs(pos-1,(lead&&i==0)?0:update(i,sta),limit && i==v[pos],lead&&(i==0));
     85             //像下面这样写也对
     86             if(lead && i==0)
     87             {
     88                 tmp+=dfs(pos-1,0,limit && i==v[pos],1);
     89 
     90             }
     91             else
     92             {
     93 
     94                 tmp+=dfs(pos-1,update(i,sta),limit && i==v[pos],0);
     95 
     96             }
     97         }
     98         if(!limit) dp[pos][sta][k]=tmp;
     99         //只有上界为9的时候才会往dp数组里面存,因为这样能节省更多的时间
    100         return tmp;
    101     }
    102     ll solve(ll ans)
    103     {
    104         ll pos=0;
    105         while(ans)
    106         {
    107             v[pos++]=ans%10;
    108             ans/=10;
    109         }
    110         return dfs(pos-1,0,true,1);
    111     }
    112     int main()
    113     {
    114         ll t,l,r,p=0;
    115         memset(w,0,sizeof(w));
    116         scanf("%I64d",&t);
    117         memset(dp,-1,sizeof(dp));
    118         while(t--)
    119         {
    120             scanf("%I64d%I64d%I64d",&l,&r,&k);
    121             printf("Case #%I64d: %I64d
    ",++p,solve(r)-solve(l-1));
    122         }
    123         return 0;
    124     }
  • 相关阅读:
    配置Gitlab pages和Gitlab CI
    程序员不应该错过的 6大导航
    Ice简介+Qt代码示例
    Android开发者的Anko使用指南(四)之Layouts
    三种方式绘制图片
    产品-(前后端)开发-测试的见解
    01_Docker概念简介、组件介绍、使用场景和命名空间
    Docker 创建 Confluence6.12.2 中文版
    读再多懂再多的鸡汤,不如每天敲码思考总结
    Postman Mock Server
  • 原文地址:https://www.cnblogs.com/kongbursi-2292702937/p/11934243.html
Copyright © 2020-2023  润新知