设为首页 加入收藏

TOP

LightOJ 1068 Investigation (数位dp)
2015-07-20 17:48:45 来源: 作者: 【 】 浏览:1
Tags:LightOJ 1068 Investigation (数位

?

求出区间[A,B]内能被K整除且各位数字之和也能被K整除的数的个数。(1 ≤ A ≤ B < 231 and 0 < K < 10000)

算是最简单的数位dp了,k在这里是10000,三维数组都开不开。但是想想会发现A,B最多有10位,各位数字之和不会超过90,那么当 k >= 90时,就不用dp,因为个位数字之和对k取余不会等于0。所以数组只需开到dp[12][90][90]。

?

?

#include 
  
   
#include 
   
     #include
     #include 
     
       #include 
      
        #include 
       
         #include 
        
          #include 
         
           #include 
          
            #include 
           
             #include 
            
              #include 
             
               #include 
              
                #define LL __int64 #define eps 1e-12 #define PI acos(-1.0) using namespace std; const int INF = 0x3f3f3f3f; const int maxn = 4010; int dp[15][92][92]; int a,b,k; int dig[15]; int dfs(int len, int mod1, int mod2, int up) { if(len == 0) return mod1 == 0 && mod2 == 0; if(!up && dp[len][mod1][mod2] != -1) return dp[len][mod1][mod2]; int res = 0; int n = up ? dig[len] : 9; for(int i = 0; i <= n; i++) { int tmod1 = (mod1*10 + i)%k; int tmod2 = (mod2 + i)%k; res += dfs(len-1,tmod1,tmod2,up&&i==n); } if(!up) dp[len][mod1][mod2] = res; return res; } int cal(int num) { int len = 0; while(num) { dig[++len] = num%10; num /= 10; } return dfs(len,0,0,1); } int main() { int test; scanf(%d,&test); for(int item = 1; item <= test; item++) { scanf(%d %d %d,&a,&b,&k); if(k >= 90) { printf(Case %d: 0 ,item); continue; } memset(dp,-1,sizeof(dp)); printf(Case %d: %d ,item,cal(b) - cal(a-1)); } return 0; } 
              
             
            
           
          
         
        
       
      
     
   
  


?

?

?

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇杭电1279 Stone Game(经典博弈) 下一篇uva 1493 - Draw a Mess(并查集)

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·C语言结构体怎么直接 (2025-12-24 17:19:44)
·为什么指针作为c语言 (2025-12-24 17:19:41)
·如何较为深入的理解c (2025-12-24 17:19:38)
·Announcing October (2025-12-24 15:18:16)
·MySQL有什么推荐的学 (2025-12-24 15:18:13)