uva11361 - Investigating Div-Sum Property 数位统计DP

Aninteger is divisible by 3 if the sum of its digits is also divisible by 3. Forexample, 3702 is divisible by 3 and 12(3+7+0+2) is also divisible by 3. Thisproperty also holds for the integer 9.

Inthis problem, we will investigate this property for other integers.

Input

The first line of input is an integer T(T<100) thatindicates the number of test cases. Each case is a line containing 3 positiveintegers A, B and K.1 <= A <= B < 2^31 and0<K<10000.

Output

For each case,output the number of integers in the range [A, B] which is divisible by K and the sumof its digits is also divisible by K.

Sample Input

Output for Sample Input

3

1 20 1

1 20 2

1 1000 4

20

5

64


  区间[A,B]中有多少个数满足:这个数能被K整除并且这个数的所有位之和能被K整除。

  用dp[i][j][k]表示i位的数有多少个每位和被K除余j,这个数被K除余K。比如i=3的时候就是000-999,i=4的时候是0000-9999...

  如果dp求出来了就好做了,区间的话只要求出[0,A-1],[0,B]相减就可以了。对于某个数A,比如3210,每位和被K除余m,这个数被K除余n。那么最高位取0,1,2的时候,后面三位是可以任取的,因此一定有一个dp[3][m'][n']与之对应,当最高位取3的时候,接着递归210,(m-3%K+K)%K,(n-3*10^3%K+K)%K。

  dp也可以用记忆化搜索,也可以递推求,道理是一样的,位数从小到大,相当于每次在最高位多加一位。dp[i][j][k]+=dp[i-1][(j-x%K+K)%K][(k-x*Pow(i-1)%K+K)%K],(0<=x<=9)。

  余数递推的时候要注意小于0的情况。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <map>
#include <iostream>
#include <algorithm>
using namespace std;
int T,A,B,K,L,dp[12][112][10010];//位数,每位和对K余数,这个数对K余数
int bit(int n,int &m){  //m是顺便算出n的最高位
    int ret=0;
    while(n){
        m=n;
        ret++;
        n/=10;
    }
    return ret;
}
int Pow(int n){
    int ret=1;
    for(int i=0;i<n;i++) ret*=10;
    return ret;
}
void init(){
    memset(dp,0,sizeof(dp));
    dp[0][0][0]=1;
    for(int i=1;i<=L;i++)
        for(int j=0;j<K&&j<=i*9;j++)
            for(int k=0;k<K;k++)
                for(int x=0;x<=9;x++) dp[i][j][k]+=dp[i-1][(j-x%K+K)%K][(k-x*Pow(i-1)%K+K)%K];
}
int solve(int n,int k1,int k2){ //[0,n) 每位和除K余k1,这个数除K余k2 
    int m,p=bit(n,m),ret=0;
    if(!p) return 0;
    for(int i=0;i<m;i++) ret+=dp[p-1][(k1-i%K+K)%K][(k2-i*Pow(p-1)%K+K)%K];
    ret+=solve(n%Pow(p-1),(k1-m%K+K)%K,(k2-m*Pow(p-1)%K+K)%K);
    return ret;
}
int main(){
    //freopen("in.txt","r",stdin);
    scanf("%d",&T);
    while(T--){
        scanf("%d%d%d",&A,&B,&K);
        int ans,t;
        L=max(bit(A,t),bit(B,t));
        if(K>(bit(B,t))*9) ans=0;
        else{
            init();
            ans=solve(B+1,0,0)-solve(A,0,0);
        }
        printf("%d\n",ans);
    }
    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
研究双层优化在学习和视觉中的应用,是为了改善学习算法和视觉系统的性能。在学习和视觉任务中,我们通常面临两个层面的优化问题。 第一层优化问题涉及到学习算法的优化,即如何通过合适的学习算法来获得最佳的模型参数。学习算法的优化过程通常涉及到定义损失函数和选择合适的优化方法。然而,常规的优化方法在高维问题中可能会面临挑战,导致在学习过程中陷入局部最优解。因此,研究者们开始探索使用双层优化方法来改进学习算法的性能。双层优化方法通过引入内部优化循环来进一步更新学习算法中的超参数,以改善模型性能。这种方法可以更好地探索参数空间,寻找更优的模型参数,从而提高学习算法的效果。 第二层优化问题涉及到视觉任务的优化,即如何通过图像处理和计算机视觉算法来解决具体的视觉问题。视觉任务可以包括目标检测、图像分割、姿态估计等多个方面。传统的视觉算法通常是通过定义特定的目标函数并使用迭代方法来进行优化。然而,这种方法可能会受到参数选择和初始条件的限制。因此,研究者们开始研究使用双层优化技术来提高视觉任务的性能。双层优化方法通过引入内部优化循环来逐步调整算法超参数和模型参数,以更好地适应特定的视觉任务。 总之,研究双层优化在学习和视觉中的应用,旨在改善学习算法和视觉系统的性能。这种方法可以通过优化学习算法的参数和模型参数,以及优化视觉任务的目标函数和算法参数,来改进学习和视觉的效果。这将有助于在学习和视觉领域取得更好的结果和应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值