简单数位Dp 数字计数

简单数位Dp 数字计数_第1张图片

其实就是10个小问题,比如就是统计 【l,r】的0的出现次数之和      1的出现次数之和......

然后就是很坑的地方在于要统计0,所以需要lead前导零标记

#include
#define int long long 
using namespace std;
const int N=35;
int dp[N][N];
int l,r;
int a[N],len;
int k;

int dfs(int pos,int sum,int lead,int limit){
	if(!pos)return sum;
	if(!limit&&!lead&&~dp[pos][sum])return dp[pos][sum];
	
	int res = 0,up = limit?a[pos]:9;
	for(int i=0;i<=up;i++){
		if(i==0&&k==0&&lead)res+=dfs(pos-1,sum,lead&&!i,limit&&i==up);
		else if(i==0&&k==0&&!lead)res+=dfs(pos-1,sum+1,lead&&!i,limit&&i==up);
		else if(i==k)res+=dfs(pos-1,sum+1,lead&&!i,limit&&i==up);
		else res+=dfs(pos-1,sum,lead&&!i,limit&&i==up);
		
	}
	
	return limit?res:(lead?res:dp[pos][sum] = res);
	
}

int cal(int x){
	memset(dp,-1,sizeof dp);
	len = 0;
	while(x)a[++len] = x%10,x/=10;
	return dfs(len,0,1,1);
}
signed main()
{
	int l,r;
	cin>>l>>r;
	for(int i=0;i<=9;i++){
		k = i;
		cout<

 

你可能感兴趣的:(DP,算法,图论,深度优先)