• hdu 4352 统计数字数位上最长上升子序列长度为k的个数


    题意:

    1245 这个数属于上升长度为4的数字,1213这个数字属于上升长度为3的数字。

    统计区间[l,r]中上升长度为k的数字个数。

    State 状态压缩,表示最长上升的序列用到的数字有哪些

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cstdlib>
     5 typedef long long LL;
     6 int const N = 22;
     7 int const M = 1030;
     8 int bit[N],ln,pow2[11],k;
     9 LL dp[N][M][20];
    10 void pre()
    11 {
    12      pow2[0]=1;
    13      for(int i=1;i<=10;i++)pow2[i]=(pow2[i-1]<<1);
    14 }
    15 LL getsum1(int t,int limit,int len,int state)
    16 {
    17    if(!t)return (len==k);
    18    if(!limit&&dp[t][state][k]!=-1)return dp[t][state][k];
    19    int up=(limit?bit[t]:9);
    20    LL ans=0;
    21    for(int i=0;i<=up;i++)
    22    {
    23        if(state||i)
    24        {
    25           if(pow2[i]>state)
    26           {
    27              ans+=getsum1(t-1,limit&&i==up,len+1,state|pow2[i]);
    28           }
    29           if(pow2[i]&state)
    30           {
    31              ans+=getsum1(t-1,limit&&i==up,len,state);
    32           }
    33           else
    34           {
    35              for(int j=i+1;j<=9;j++)
    36              {
    37                  if(state&pow2[j])
    38                  {
    39                     ans+=getsum1(t-1,limit&&i==up,len,state^pow2[j]|pow2[i]);
    40                     break;
    41                  }
    42              }
    43           }
    44        }
    45        else
    46        {
    47           ans+=getsum1(t-1,limit&&i==up,0,0);
    48        }
    49    }
    50    if(!limit)dp[t][state][k]=ans;
    51    return ans;
    52 }
    53 LL getsum2(LL n)
    54 {
    55    if(n==0)return 0;
    56    for(ln=0;n;bit[++ln]=n%10,n/=10);
    57    return getsum1(ln,1,0,0);
    58 }
    59 int main()
    60 {
    61     pre();
    62     memset(dp,-1,sizeof(dp));
    63     int T,t=0;
    64     k=2;
    65     scanf("%d",&T);
    66     while(T--)
    67     {
    68           LL l,r;
    69           scanf("%I64d %I64d",&l,&r);
    70           scanf("%d",&k);
    71           l--;
    72           printf("Case #%d: %I64d\n",++t,getsum2(r)-getsum2(l));
    73     }
    74     return 0;
    75 }
    View Code
  • 相关阅读:
    CF869E The Untended Antiquity 解题报告
    Walk 解题报告
    CF911F Tree Destruction 解题报告
    P4397 [JLOI2014]聪明的燕姿
    洛谷 P2329 [SCOI2005]栅栏 解题报告
    洛谷 P3747 [六省联考2017]相逢是问候 解题报告
    set-erase
    set-empty
    set-empty
    set-end
  • 原文地址:https://www.cnblogs.com/nuoyan2010/p/3091321.html
Copyright © 2020-2023  润新知