给定一个十进制正整数N,写下从1开始,到N的所有正数,计算出其中出现所有1的个数。
例如:n = 12,包含了5个1。1,10,12共包含3个1,11包含2个1,总共5个1。
数位dp的模板题
这里的flag表示1的数量
#include<iostream> #include<cstring> using namespace std; int a[1000],dp[100][100]; int dfs(int pos,int flag,int limit) { int ans=0,sum=0; if(!pos) return flag; if(!limit&&dp[pos][flag]!=-1) return dp[pos][flag]; int num=limit?a[pos]:9; for(int i=0;i<=num;i++) { if(i==1) ans+=dfs(pos-1,flag+1,limit&&i==num);//当前位数有1,flag+1,flag表示1的数量 else ans+=dfs(pos-1,flag,limit&&i==num); } if(!limit&&dp[pos][flag]==-1) dp[pos][flag]=ans; sum+=ans; return sum; } int solve(int n) { memset(a,0,sizeof(a)); int len=0; while(n) { a[++len]=n%10; n=n/10; } return dfs(len,0,1); } int main() { int n; memset(dp,-1,sizeof(dp)); cin>>n; cout<<solve(n)<<endl; return 0; }