LightOJ-1140-数位dp

来源:互联网 发布:灭门案 知乎 编辑:程序博客网 时间:2024/06/18 00:36

题目大意:给定区间问区间内所有数的10进制0的个数的总和是多少;

题目解析:dp的第二维表示当前已经有多少个0,注意前导零和只有1个0要输出1;

AC代码:

#include<iostream>  #include<cstdio>  #include<cstring>  #include<string>  #include<algorithm>  using namespace std;  typedef long long ll;  ll dp[35][300];  int num[35];  ll dfs(int pos,int cnt,bool lead,bool limit)  {  if(pos==-1&&lead==true)return 1;    if(pos==-1) return cnt;      if(!lead&&!limit&&dp[pos][cnt]!=-1) return dp[pos][cnt];      int u=limit?num[pos]:9;      ll ans=0;      for(int i=0;i<=u;i++)      {          if(lead&&i==0)  ans+=dfs(pos-1,0,true,limit&&i==u);else if(i==0)ans+=dfs(pos-1,cnt+1,lead&&i==0,limit&&i==u);          else     ans+=dfs(pos-1,cnt,lead&&i==0,limit&&i==u);       }      if(!lead&&!limit)   return dp[pos][cnt]=ans;      return ans;  }  ll solve(ll n)  {      ll cnt=0;      while(n)      {          num[cnt++]=n%10;          n/=10;      }      return dfs(cnt-1,0,true,true);  }  int main()  {      ll a,b;      memset(dp,-1,sizeof(dp)); int cas,c=1;scanf("%d",&cas);     while(cas--)      {      scanf("%lld%lld",&a,&b);    printf("Case %d: ",c++);        printf("%lld\n",solve(b)-solve(a-1));                 }      return 0;  }  


0 0
原创粉丝点击