2020 hdu多校赛 第三场 1006 X Number

题意:

每次给你  L R d,问L~R中有多少个数 x 满足 x 各个位上的数 d 为唯一众数  ,如23323 中的 3,10000中的0,但是2233对于2和3都不算。(L<=1e18,R<=1e18,0<=d<=9)

很显然,这是一个数位DP,按照数位DP的套路,我们需要计算从高到低前x-1位已经固定,第x位填y时,满足题意的数有多少。

由于L,R只有1e18,我们不妨枚举d在剩下那几位中出现的次数,然后通过记忆化搜索 / 背包DP 求解。

不过这只是整体思路。在枚举第一位为0时,我们还需要对于前导0特殊处理。总之细节很多,详情见代码。

  1 #include<iostream>
  2 #include<cstdlib>
  3 #include<cstdio>
  4 #include<algorithm>
  5 #include<cstring>
  6 #include<cmath>
  7 #define N 25
  8 using namespace std;
  9 int T;
 10 long long L,R,d;
 11 int A[N],zz;
 12 int cnt[N],D[N];
 13 long long C[N][N];
 14 long long F[11][19][19];
 15 long long dfs(int x,int mx,int sm)
 16 {
 17     if(x==10)
 18     {
 19         if(sm==0)return 1;
 20         else return 0;
 21     }
 22     if(x==d) return dfs(x+1,mx,sm);
 23     if(F[x][mx][sm]!=-1)return F[x][mx][sm];
 24     long long ans=0;
 25     for(int i=0;i<=sm&&i+D[x]<mx;i++)
 26     {
 27         ans+=1ll*C[sm][i]*dfs(x+1,mx,sm-i);
 28     }
 29     return F[x][mx][sm]=ans;
 30 }
 31 long long work(long long x)
 32 {
 33     zz=0;
 34     x++;
 35     memset(cnt,0,sizeof(cnt));
 36     long long tmp=x;
 37     while(tmp)
 38     {
 39         zz++;
 40         A[zz]=tmp%10;
 41         tmp/=10;
 42     }
 43     for(int i=1;i<=zz/2;i++)
 44     {
 45         swap(A[i],A[zz-i+1]);
 46     }
 47     long long ans=0;
 48     memset(D,0,sizeof(D));
 49     for(int i=1;i<=zz;i++)
 50     {
 51         for(int j=0;j<A[i];j++)
 52         {
 53             if(i==1&&j==0)
 54             {
 55                 if(d!=0)
 56                 {
 57                     memset(F,-1,sizeof(F));
 58                     for(int k=1;k<zz;k++)
 59                     {
 60                         for(int l=1;l<=k;l++)
 61                         {
 62                             for(int o=0;o<l;o++)
 63                             {
 64                                 ans+=C[k-1][o]*C[k-o][l]*dfs(1,l,k-l-o);
 65                 
 66                             }
 67                         }
 68                     }
 69                 }
 70                 else
 71                 {
 72                     memset(F,-1,sizeof(F));
 73                     for(int k=1;k<zz;k++)
 74                     {
 75                         for(int l=1;l<k;l++)
 76                         {
 77                             ans+=C[k-1][l]*dfs(1,l,k-l);
 78                         }
 79                     }
 80                 }
 81                 continue;
 82             }
 83             cnt[j]++;
 84             D[j]++;
 85             int mx=0;
 86             for(int k=0;k<=9;k++)
 87             {
 88                 if(k==d) continue;
 89                 mx=max(mx,cnt[k]);
 90             }
 91             if(mx>=cnt[d])
 92             {
 93                 memset(F,-1,sizeof(F));
 94                 for(int k=mx-cnt[d]+1;k<=zz-i;k++)
 95                 {
 96                     ans+=C[zz-i][k]*dfs(0,k+cnt[d],zz-i-k);
 97                 }
 98             }
 99             else
100             {
101                 memset(F,-1,sizeof(F));
102                 for(int k=0;k<=zz-i;k++)
103                 {
104                     ans+=C[zz-i][k]*dfs(0,k+cnt[d],zz-i-k);
105                 //    if(x==239) cout<<i<<' '<<j<<' '<<k<<' '<<ans<<' '<<dfs(1,k+cnt[d],zz-i-k)<<endl;
106                 }
107             }
108             cnt[j]--;
109             D[j]--;
110             
111         }
112         cnt[A[i]]++;
113         D[A[i]]++;
114     }
115     return ans;
116 }
117 int main()
118 {
119 //    freopen("test.in","r",stdin);
120 //    freopen("1.out","w",stdout);
121     C[0][0]=1;
122     for(int i=1;i<=19;i++)
123     {
124         C[i][0]=1;
125         for(int j=1;j<=i;j++) C[i][j]=C[i-1][j]+C[i-1][j-1];
126     }
127     scanf("%d",&T);
128     while(T--)
129     {
130         scanf("%lld%lld%lld",&L,&R,&d); 
131         printf("%lld\n",work(R)-work(L-1));
132     //    cout<<work(R)<<' '<<work(L-1)<<endl;
133     }
134     return 0;
135 }
136 /*
137 1
138 926 949 9
139 
140 
141 3
142 23123 243353 0
143 23123 243353 5
144 23123 243353 9
145 
146 2
147 1 1000 0
148 101 1000 0
149 */
View Code
posted @ 2020-07-29 11:08  Hzoi_joker  阅读(438)  评论(0编辑  收藏  举报