zoukankan      html  css  js  c++  java
  • Lightoj 1068(数位DP)

    求一段区间中被k整除,各个位数相加之和被k整除的数的个数。

    这不是重点,重点是k太大了,最大值有10000,所以不能直接开那么大的数组。

    仔细分析一下可以发现,由于数最大是2的31次方(2147483648),所以当k>90时,直接输出0即可。

    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <iostream>
    using namespace std;
    #define LL  long long
    #define maxn 30
    LL  dp[maxn][100][100];
    LL  digit[maxn];
    LL  n,m,K;
    LL dfs(int len,LL pre,LL before,bool fp)
    {
        if(!len)
        {
           return pre==0&&before==0;
        }
        if(!fp && dp[len][pre][before] != -1)
            return dp[len][pre][before];
        LL   ret = 0 ;
        LL   fpmax = fp ? digit[len] : 9;
        for(int i=0;i<=fpmax;i++)
        {
            ret += dfs(len-1,(pre*10+i)%K,(before+i)%K,fp && i == fpmax);
        }
        if(!fp)
            dp[len][pre][before] = ret;
        return ret;
    }
    
    LL f(LL n)
    {
        int len = 0;
        while(n)
        {
            digit[++len] = n % 10;
            n /= 10;
        }
        return dfs(len,0,0,true);
    }
    
    void init()
    {
        memset(dp,-1,sizeof(dp));
    }
    int main()
    {
        //freopen("test.txt","r",stdin);
      // cout<< ((LL)1<<31)<<endl;
          int t;
         scanf("%d",&t);
         int Case=0;
         while(t--)
         {
              scanf("%d%d%d",&n,&m,&K);
              if(K>90)
              {
                  printf("Case %d: 0
    ",++Case);
                  continue;
              }
              init();
                printf("Case %d: %lld
    ",++Case,f(m)-f(n-1));
         }
        return 0;
    }
  • 相关阅读:
    「开始,DP专题」
    ZOJ3612 Median treap
    [HNOI2004]宠物收养所 treap
    SIRO Challenge 状态压缩 + DP 未解
    SPOJ3273 Order statistic set treap模板
    HNU2[I题]Omar Loves Candies 贪心
    HNU1[B题] DP,数位DP
    HNU1[F题] 栈模拟计算
    Node.js权威指南 (6)
    瘦下来之后你会遇见不一样的自己
  • 原文地址:https://www.cnblogs.com/xianbin7/p/4759532.html
Copyright © 2011-2022 走看看