数位dp就是套模板 ——lwz dalao
模板
( ( ext{dfs}) 式数位 ( ext{DP}) ):
ll dfs(ll len,bool Limit,bool zero,ll …… ) // 其他各种条件
{
if(len>w) return zero^1; // 注意!!!特判 0
if(!Limit && dp[len][……]!=-1) return dp[len][……];
ll ret=0;
for(ll i=0;i<=9;i++)
{
if(Limit && i>num[len]) break; // 只有在有 Limit 最高位限制是才需要判断是否高于最高位
if(……) // 根据题目满足各种条件
}
if(!Limit && !zero) dp[len][……]=ret; // 必须同时满足没有最高位与前导 0 限制
return ret;
}
ll solve(ll x)
{
memset(dp,-1,sizeof(dp)); // 有时要每一次都赋值!!!
ll w=0,tmp=x;
while(tmp) num[++w]=tmp%10,tmp/=10; // 统计位数
// 有的情况下应在这里给 dp 数组赋值
return dfs(w,1,1,……);
}
memset(dp,-1,sizeof(dp)); // 有时只用赋值一次!!!
例题
P4317 花神的数论题
题意:统计 (n) 以内正整数的二进制中 (1) 的个数之积。
枚举 (k=1dots log_2^n) ,分别计算二进制中 (1) 的个数为 (k) 时的数的个数,最后相乘即可。
P2657 [SCOI2009] windy 数
P2602 [ZJOI2010]数字计数
统计 ([1,n]) 中 (0dots 9) 每一个数位分别出现多少次。
模板吧~