【51NOD】数字1的数量
【算法】数位DP
【题解】数位dp总结 之 从入门到模板
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int maxn=20; int n,a[maxn],NUM[maxn]; long long f[maxn]; struct cyc{int num/*数字数*/;long long ans/*1的数量*/;}qp; cyc dfs(int deep,bool limit)//返回1的个数 { if((f[deep]!=-1&&!limit)||deep==0) { qp.num=NUM[deep]; qp.ans=f[deep]; return qp; } int k=limit?a[deep]:9; int sum=0;long long ans=0; for(int i=0;i<=k;i++) { qp=dfs(deep-1,limit&&i==k); if(i==1)ans+=qp.num; ans+=qp.ans; sum+=qp.num; } if(!NUM[deep]&&!limit)NUM[deep]=sum; if(f[deep]==-1&&!limit)f[deep]=ans; qp.ans=ans;qp.num=sum; return qp; } int main() { scanf("%d",&n); int k=n;int N=0; while(k>0) { N++; a[N]=k%10; k/=10; } memset(f,-1,sizeof(f)); NUM[0]=1;f[0]=0; printf("%lld",dfs(N,1).ans); return 0; }