【UER #4】被粉碎的数字

题意

很久很久以前,有一个数字加入了 UOJ 群。

这天,在它讨论“一个数字应该怎么取模”的时候一不小心被删除了,变成了被粉碎的数字。

突然间,它突然发现它忘记了自己是谁。这让它感觉很焦躁,于是它来拜托你来帮它找到它所代表的整数 x。

在经过一番询问之后,你整理了一下现在你得到的线索:

已知整数 R,有 1≤x≤R
定义函数 f(x) 为 x 的各位数字之和,例如 f(13)=4,f(233)=8。已知整数 k,有 f(x)=f(k×x)
然而遗憾的是,你发现即使拥有了这些条件,可能的 x 依然有很多个。因此,为了进一步缩小排查范围,你想要知道满足这两个条件的整数有多少个。

60%特殊的打表技巧

若我们一个一个算f(x)会只能得30分,但我们可以打 106 的表,那么计算时我们可以这样写: f(x)=f(x/106)+f(xmod106)
这样便可以多拿30分了。

分析

数位dp..
感觉自己掌握的不够熟练,一出类似的题不能很快想出来。
f[i,sum,sum1,r,p] 为(从低位到高位)第i位,原数前i位的数字和为sum,原数乘上k的数的数字和为sum1,原数上次乘k的数的进位r,和这个数是否比R大,p,的数字的个数。
首先明显的乘法,所以只能从低到高(和上次的光棍不同。。)
而这个转移也是比较轻松的:
f[i+1][sum+chmod10][sum1+(kch+r)mod10][(kch+r)/10][p]+=f[i][sum][r][pd];
但是转移时间过大,所以我们只能继续优化:
我们发现我们最后要求的是sum=sum1,所以我们可以把它转化成差的形式:
f[i+1][sum+ch(kch+r)mod10][kch+r)/10][p]+=f[i][sum][r][pd];
到此便可以很好解决问题了。

注意

但是求答案时我们却不能认为答案为 f[bit[0]][0][0] ,因为我们会发现这里依然会有进位,所以我们只能再算几次,把它的进位算完(多的几位,可以理解成这几位选0即可)再统计答案。

还有这题和之前的光棍不同,因为要乘法就要从低位算,而不用乘法的,可以从高位算,便可以直接统计答案,无需多算。

注意边界的计算,进位最多999,差最多20*10*2=400;
(请读者思考)
最后可能读者看完下面的程序后会认为f会多算一些比R要大的数,但是我们再统计答案时强制让数为小于等于R即p=0;

#include<cstdio>
#include<cstdlib>
#define fo(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
int k,bit[25],p,x,y;
long long f[25][410][1005][2],t;
int main(){
    scanf("%lld%lld",&t,&k);
    int po=0;
    while (t!=0) bit[++po]=t%10,t=t/10;
    f[0][200][0][0]=1;
    fo(i,0,po+2)
        fo(r,0,999)
      fo(sum,0,400)
          fo(pd,0,1)
            if (f[i][sum][r][pd])
            fo(ch,0,9){
                if (ch>bit[i+1]) p=1;
                else if (ch<bit[i+1]) p=0;
                else p=pd;
                x=(k*ch+r)/10;y=sum+ch-(k*ch+r)%10;
                f[i+1][y][x][p]+=f[i][sum][r][pd];
            }
    printf("%lld",f[po+3][200][0][0]-1);=
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值