zoukankan      html  css  js  c++  java
  • NEUQ OJ 2004:追梦之人 (计数数位dp)

    2004: 追梦之人

    描述

    题目描述:

    为了纪念追梦人,粉丝们创造了一种新的数——“追梦数”。追梦数要满足以下两个条件:
    1、数字中不能出现“7”
    2、不能被7整除。
    比如:777和4396就不是追梦数,而666是追梦数。现在他们想知道,1到N中有多少个追梦数。

    输入:

    多组数据。
    第一行给出一个正整数T。T为数据组数。
    接下来T行,每行包括一个正整数N。
    (1 leq T leq 10001T1000
    (1 leq N leq 10^{18}1N1018)

    输出:

    对于每组数据,在单独的一行中输出一个整数表示1到N中有多少个追梦数。

    样例输入
    4
    10
    14
    17
    100
    样例输出
    9
    12
    14
    70

    当初石乐志要维护三个东西,后来发觉数位只要维护两个东西就好了。
    我们的答案是n-被7整除的数-不被7整除但包含7的数。
    被7整除的数n/7即可求出。
    后面这个写个数位dp即可。
    dpi[k]表示长度为i,膜7的余数为j,是否含7的情况为k(k为0表示不含,为1表示含)的数的数量,考虑当前的第i位为x,之前的i-1位组成的数膜7的余数为y,那么dpi+=dpi-1。如果x不是7,那么k应该是0转移到0,1转移到1;如果x是7,那么都转移到k=1。剩下的就是裸的数位dp了。
    注意边界。

     1 #include<bits/stdc++.h>
     2 #define clr(x) memset(x,0,sizeof(x))
     3 #define clr_1(x) memset(x,-1,sizeof(x))
     4 #define mod 7
     5 #define LL long long
     6 #define INF 0x3f3f3f3f
     7 #define mp make_pair
     8 #define pb push_back
     9 #define mp make_pair
    10 #define fi first
    11 #define se second
    12 using namespace std;
    13 const int N=1e5+10;
    14 LL all[30][10][2],num[30];
    15 void init()
    16 {
    17     all[0][0][0]=1;
    18     num[1]=1;
    19     for(int i=2;i<=18;i++)
    20         num[i]=(num[i-1]*10)%mod;
    21     for(int i=1;i<=18;i++)
    22         for(int j=0;j<=9;j++)
    23             for(int k=0;k<7;k++)
    24                 if(j!=7)
    25                 {
    26                     all[i][(int)(j*num[i]%mod+k)%mod][1]+=all[i-1][k][1];
    27                     all[i][(int)(j*num[i]%mod+k)%mod][0]+=all[i-1][k][0];
    28                 }
    29                 else
    30                      all[i][(int)(j*num[i]%mod+k)%mod][1]+=all[i-1][k][1]+all[i-1][k][0];
    31 }
    32 LL n,m,k;
    33 LL ans;
    34 int a[N],t,now;
    35 bool flag;
    36 int T;
    37 int main()
    38 {
    39     init();
    40     scanf("%d",&T);
    41     while(T--)
    42     {
    43         scanf("%lld",&n);
    44         ans=n-n/7;
    45         m=0;
    46         n++;
    47         while(n)
    48         {
    49             a[++m]=n%10;
    50             n/=10;
    51         }
    52         now=0;
    53         flag=0;
    54         for(int i=m;i>=1;i--)
    55         {
    56             for(int j=0;j<a[i];j++)
    57             {
    58                 for(int k=0;k<mod;k++)
    59                     if((j*num[i]%mod+k+now)%mod!=0)
    60                     {
    61                         ans-=all[i-1][k][1];
    62                         if(flag || j==mod)
    63                             ans-=all[i-1][k][0];
    64                     }
    65             }
    66             now=(now+a[i]*num[i])%mod;
    67             if(a[i]==mod)
    68                 flag=1;
    69         }
    70         printf("%lld
    ",ans);
    71     }
    72 }
    View Code
  • 相关阅读:
    973. K Closest Points to Origin
    919. Complete Binary Tree Inserter
    993. Cousins in Binary Tree
    20. Valid Parentheses
    141. Linked List Cycle
    912. Sort an Array
    各种排序方法总结
    509. Fibonacci Number
    374. Guess Number Higher or Lower
    238. Product of Array Except Self java solutions
  • 原文地址:https://www.cnblogs.com/wujiechao/p/9034305.html
Copyright © 2011-2022 走看看