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