zoukankan      html  css  js  c++  java
  • nowcoder A hard problem /// 数位DP

    题目大意:

    称一个数x的各个数位之和为f(x)

    求区间L R之间 有多少个数x%f(x)==0

    #include <bits/stdc++.h>
    using namespace std;
    #define INF 0x3f3f3f3f
    #define LL long long
    #define inc(i,j,k) for(int i=j;i<=k;i++)
    #define dec(i,j,k) for(int i=j;i>=k;i--)
    #define gcd(i,j) __gcd(i,j)
    #define mem(i,j) memset(i,j,sizeof(i))
    const int N=2e5+5;
    
    int rd, dfn[2][15][50][50];
    int fx, tot, a[15];
    LL dp[2][15][50][50];
    // dp[f][w][s][m]
    // f为1说明不是上界 此时为第w位数 
    // 剩下的数位总和为s 此时的数位总和%f(x)为m
    
    LL DFS(int f,int w,int s,int m) {
        if(w==0) return (s==0&&m==0);
        // 所有位都枚举过了则w=0
        // 所有数位总和为fx则s=0
        // x%fx==0则m=0
        if(dfn[f][w][s][m]==rd) return dp[f][w][s][m];
        dfn[f][w][s][m]=rd;
        LL res=0LL;
        int l=max(0,s-9*(w-1)), r=min((f ? 9:a[w]),s);
        for(int i=l;i<=r;i++) // 枚举当前位的数
            res+=DFS(f|(i<a[w]),w-1,s-i,(m*10+i)%fx);
        // 之前不是上界 或 当前位不是上界 则到目前为止都不达上界
        // 位数-1 剩余数位总和需减去当前位的数 更新余数
        return dp[f][w][s][m]=res;
    }
    
    LL solve(int x) {
        mem(dp,0); mem(dfn,0);
        int tot=0;
        while(x) { a[++tot]=x%10; x/=10; }
        int all=tot*9;
        LL res=0LL;
        for(fx=1;fx<=all;fx++) // 枚举所有数位总和
            ++rd, res+=DFS(0,tot,fx,0);
        //printf("%lld
    ",res);
        return res;
    }
    
    int main()
    {
        int _; scanf("%d",&_);
        inc(i,1,_) {
            int l,r; scanf("%d%d",&l,&r); rd=0;
            printf("Case %d: ",i);
            printf("%lld
    ",solve(r)-solve(l-1));
        }
    
        return 0;
    }
  • 相关阅读:
    走进AngularJs(二) ng模板中常用指令的使用方式
    mysql知识汇总
    存储动态数据时,数据库的设计方法
    js判断密码强度
    svg―Raphael.js Library(一)
    常用js代码
    IE6实现图片或背景的圆角效果
    巧用css border
    IE6下的效果
    理解盒模型
  • 原文地址:https://www.cnblogs.com/zquzjx/p/10658155.html
Copyright © 2011-2022 走看看