数位DP模板

数位DP模板

  • 最容易忽略的一点:l==0的时候要加特判
int l,r,len,...;
int dp[][][][]...;
int bit[];

inline int dfs(int pos,int pre,int st,……,bool lead,bool limit){
    if(pos>len) return st;//剪枝
    if((dp[pos][pre][st]……[……]!=-1&&(!limit)&&(!lead))) return dp[pos][pre][st]……[……];//记录当前值
    int res=0;//暂时记录当前方案数
    int res=limit?bit[len-pos+1]:9;//res当前位能取到的最大值
    for(int i=0;i<=res;i++){
        //有前导0并且当前位也是前导0
        if(i==0 && lead) ret+=dfs(……,……,……,i==res&&limit);
        //有前导0但当前位不是前导0,当前位就是最高位
        else if(i && lead) ret+=dfs(……,……,……,i==res&&limit); 
        else if(根据题意而定的判断) ret+=dfs(……,……,……,i==res&&limit);
    }
    if(!limit && !lead) dp[pos][pre][st]……[……]=res;//当前状态方案数记录
    return res;
}

inline int work(int x){//按数位拆分
    len=0;
	mem(dp,-1);//初始化-1(因为有可能某些情况下的方案数是0)
    while(x){
		bit[++len]=x%10;
		x/=10;
	}
    return dfs(……,……,……,……);//进入记搜
}

#undef int 
int main(){
#define int long long
	rd(T);
	while(T--){
		rd(l),rd(r);
        if(l) printf("%lld",part(r)-part(l-1));//[l,r](l!=0)
        else printf("%lld",part(r)-part(l));//从0开始要特判
    }
    return 0;
}
原文地址:https://www.cnblogs.com/sjsjsj-minus-Si/p/11637619.html