洛谷P2602对于第一篇题解的详细解释

dp[i]是什么意思?

i表示位数,例如1表示数字只有1位(0~9),2表示数字有2位(00~99)

所以这种情况是有前导0的出现的,例如dp[i]的情况里面有01、02

dp[i]的值表示包括前导零,任意一个数字总共出现了多少次,例如dp[2]为20,1对应的情况有:

01、21、31···91,10~19

转移方程是什么意思?

dp[i]=dp[i-1]*10+10^(i-1);

这里假如统计的是1的出现情况次数。

加号前部分表示统计非最高位的1出现次数,因为高位可以为0到9,所以这里乘10

加号后半部分表示统计最高位1出现的次数,所以1固定在最高位,后面的i-1位进行排列组合

    for(int p=len;p>=1;p--){
        //
        for(int i=0;i<=9;i++)
          ans[i]+=a[p]*dp[p-1];
        for(int i=0;i<a[p];i++)
          ans[i]+=base[p];
        ll cnt=0;
        for(int i=p-1;i>=1;i--){
            cnt=cnt*10+a[i];
        }
        ans[a[p]]+=cnt+1;
        // 这里的含义不一样
        ans[0]-=base[p];
    }

以下问题都建立在22345这样一个例子的情况下。

第一个内循环表示什么意思呢?

计算0~(10000-1)的方案情况,这里会出现前导零的问题(dp导致的),所以后续需要减去

计算10000~(20000-1)的方案情况,这里没有前导零的问题,因为最高位为1

第二个内循环表示什么意思呢?

这里为什么是从0开始,不是从1开始呢,因为最高位不为0,是允许出现前导零的情况的,这里所有的ans[0]被剪掉的情况,都是在处理0~(10000-1)这种情况

如果第一次外循环,肯定能进第二个内循环(因为最高位一定不为0),所以要剪掉为前导0的情况,后续循环减去前导0的情况都是在处理0~(10000-1)这种情况

为什么22345处理完最高位2后,还要再处理2345这种情况呢,不会重复吗?

不会,因遍历到2时,处理的时0~20000以及最高位为2的情况,还没有处理2xxxx这4个x的方案情况,所以还需要单独拧出来去处理,这里不是2235,而是带了一个前缀的2-2235

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值