标签:
3 1 100 500
0 1 5
From 1 to 500, the numbers that include the sub-sequence "96" are "96","196","296","396","496",so the answer is 5.
题意:
问[1,n]中有多少个数中包含96;
思路:
数位dp的题,跟有一道hdu的数位dp一样;哎,还没理解记忆化搜索的写法;有时间看看去;
AC代码:
#include <bits/stdc++.h> using namespace std; #define Riep(n) for(int i=1;i<=n;i++) #define Riop(n) for(int i=0;i<n;i++) #define Rjep(n) for(int j=1;j<=n;j++) #define Rjop(n) for(int j=0;j<n;j++) #define mst(ss,b) memset(ss,b,sizeof(ss)); typedef long long LL; const LL mod=1e9+7; const double PI=acos(-1.0); const int inf=0x3f3f3f3f; const int N=1e6+5e5; LL dp[25][3],n; int b[25]; //dp[i][0]表示长度<=i包含96的个数; //dp[i][1]表示长度为i不包含96但开头为6的个数 //dp[i][2]表示<=i不包含96的个数; int fun() { mst(dp,0); dp[0][2]=1LL; for(int i=1;i<23;i++) { dp[i][0]=dp[i-1][0]*10+dp[i-1][1]; dp[i][1]=dp[i-1][2]; dp[i][2]=dp[i-1][2]*10-dp[i-1][1]; } } int main() { int t; scanf("%d",&t); fun(); while(t--) { scanf("%lld",&n); LL temp=n,ans=0; int cnt=1; while(temp) { b[cnt++]=temp%10; temp/=10; } b[cnt]=0; int flag=0; for(int i=cnt;i>0;i--) { ans+=dp[i-1][0]*(LL)b[i]; if(flag)//如果前边已经出现了96那么就还要加上后面不含96的方案数; { ans+=dp[i-1][2]*b[i]; } if(b[i+1]==9&&b[i]==6) { flag=1; } } if(flag)ans++;//如果96出现的位置后面全是0 printf("%lld\n",ans); } return 0; }
标签:
原文地址:http://www.cnblogs.com/zhangchengc919/p/5469119.html