zoukankan      html  css  js  c++  java
  • Gym

    给定n∈[1,1e12],求1到n的所有整数中,各位数字之和能整除它本身的数的个数。

    这道题与UVA-11361类似,假如设dp[u][lim][m1][m2]为枚举到第u位(从低到高数),是否受限,各位之和为m1,本身为m2时继续往下枚举能得到的答案数,可以得到正确的答案。但m2过大不能直接作为状态保存,如果对各位之和取模的话,又会发现dp的过程中模数是不确定的,怎么办?

    解决方法是枚举模数,也就是枚举各位之和k,这样模数就固定了,就可以轻松地往下转移了。边界条件为u<0&&m1==k&&m2==0,状态转移方程见代码。

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 typedef long long ll;
     5 const ll N=12+2;
     6 ll bit[N],nb,d[N][2][130][130],a,b,k;
     7 ll dp(ll u,ll lim,ll m1,ll m2) {
     8     if(u<0) {
     9         if(m1==k&&m2==0)return 1;
    10         return 0;
    11     }
    12     ll& ret=d[u][lim][m1][m2];
    13     if(~ret)return ret;
    14     ret=0;
    15     for(ll i=0; i<=(lim?bit[u]:9); ++i)ret+=dp(u-1,lim&&i==bit[u],m1+i,(m2*10+i)%k);
    16     return ret;
    17 }
    18 
    19 ll getans(ll x) {
    20     ll ans=0;
    21     for(nb=0; x; x/=10)bit[nb++]=x%10;
    22     for(k=1; k<=120; ++k) {
    23         memset(d,-1,sizeof d);
    24         ans+=dp(nb-1,1,0,0);
    25     }
    26     return ans;
    27 }
    28 
    29 int main() {
    30     freopen("just.in","r",stdin);
    31     freopen("just.out","w",stdout);
    32     ll n;
    33     scanf("%lld",&n);
    34     printf("%lld
    ",getans(n));
    35     return 0;
    36 }
  • 相关阅读:
    NOP源码分析六--实体、数据的分层与处理。
    NOP源码分析七---继续
    NOP源码分析 八---set的存储
    Nop 源码分析四 任务系统
    NOP源码分析五,文件位置等详细内容,感冒真难受,嗓子痒又疼。。
    1
    mobx
    ts随笔
    13.vue-vuex
    13.vue-axios
  • 原文地址:https://www.cnblogs.com/asdfsag/p/10350635.html
Copyright © 2011-2022 走看看