zoukankan      html  css  js  c++  java
  • hdu 4352 数位dp+nlogn的LIS

    题意:求区间L到R之间的数A满足A的的数位的最长递增序列的长度为K的数的个数。

    链接:点我

    该题的关键是记录LIS的状态,学习过nlogn解法的同学都知道,我们每次加入的元素要和前面的比对替换,这里就用了这个方法

    比如1 3 6,用二进制表示为001000101,假如新加入的数为2,那么我们枚举比2大的数,观察是否存在,这里找到3,我们把3替换成2,状态变成1,2,6

    不懂的童鞋可以看这里的nlogn的介绍:点我

    还有就是注意前导0

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<queue>
     7 #include<map>
     8 using namespace std;
     9 #define MOD 1000000007
    10 typedef long long ll;
    11 const int INF=0x3f3f3f3f;
    12 const double eps=1e-5;
    13 #define cl(a) memset(a,0,sizeof(a))
    14 #define ts printf("*****
    ");
    15 const int MAXN=1005;
    16 int n,m,tt,K;
    17 ll dp[20][1<<11][11];
    18 int digit[20];
    19 int k;
    20 ll getst(ll s,ll u,ll& xx)  // 状态转移
    21 {
    22     ll i,ss;
    23     for(i=u;i<10;i++)
    24     {
    25         if(s&(1<<i)) break ;    //有比u大的,替换掉
    26     }
    27     if(i<10)
    28     {
    29         ss=s^(1<<i);
    30         ss=ss^(1<<u);
    31     }
    32     else    //没有比u大的,u放入s中
    33     {
    34         xx++;
    35         ss=s^(1<<u);
    36     }
    37     return ss;
    38 }
    39 ll dfs(int p,ll s,ll len,int fl,bool e) {    //位置,lis状态,lis长度,前导0
    40     if (p==-1) return len==k;
    41     if (!e &&dp[p][s][k]!=-1) return dp[p][s][k];
    42     ll res = 0;
    43     int u=e?digit[p]:9;
    44     for (int i=0;i<=u;++i)
    45     {
    46         ll ns,nlen=len;
    47         if(fl==0&&i==0) ns=0;
    48         else    ns=getst(s,i,nlen);
    49         res+=dfs(p-1,ns,nlen,fl||i!=0,e&&i==u);
    50     }
    51     return e?res:dp[p][s][k]=res;
    52 }
    53 ll solve(ll n)
    54 {
    55     int len=0;
    56     while(n)
    57     {
    58         digit[len++]=n%10;
    59         n/=10;
    60     }
    61     return dfs(len-1,0,0,0,1);
    62 }
    63 int main()
    64 {
    65     int i,j;
    66     #ifndef ONLINE_JUDGE
    67     freopen("1.in","r",stdin);
    68     #endif
    69     scanf("%d",&tt);
    70     int ca=0;
    71     memset(dp,-1,sizeof(dp));
    72     while(tt--)
    73     {
    74         ll l,r;
    75         scanf("%I64d%I64d%I64d",&l,&r,&k);
    76         ll ans=solve(r)-solve(l-1);
    77         printf("Case #%d: %I64d
    ",++ca,ans);
    78     }
    79 }
  • 相关阅读:
    条款 15:在资源管理类中提供对原始资源的访问
    Python利器一之requests
    flask_入门教程之一
    Python面试题之一:解密
    珍藏版 Python 开发工程师面试试题
    Python处理Sqlite3数据库
    App自动化测试前期准备---android SDK配置
    QA 、 QC & QM软件测试入门专业名词解释 -- 灌水走起
    Nodejs的那些事
    你的第一个自动化测试:Appium 自动化测试
  • 原文地址:https://www.cnblogs.com/cnblogs321114287/p/4265368.html
Copyright © 2011-2022 走看看