題目連結
題意就是如果一個數字裡包含49這個子數字(子串…),那麼分數+1
問1-N之間能得到多少分數
這個題和不要62基本一樣,都是入門數位dp題……
只需要去掉一個條件即可.
這裡再簡單的說下.
dp[ i ] [ j ]代表 該數位位元為 i ,最高位為 j 時合格有多少個
例如dp[ 2 ] [ 4] =9 (合格數有 40,41,42,43,44,45,46,47,48)
打好表之後,再按照N+1從高位到低位統計出 不帶49的數位個數.最後n+1-這個答案即可.
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<cmath>#include<iomanip>#include<algorithm>#define max(a,b) (a>b?a:b)#define min(a,b) (a<b?a:b)#define swap(a,b) (a=a+b,b=a-b,a=a-b)#define memset(a,v) memset(a,v,sizeof(a))#define X (sqrt(5)+1)/2.0 //Wythoff#define Pi acos(-1)#define e 2.718281828459045#define eps 1.0e-8using namespace std;typedef long long int LL;typedef pair<int,int> pa;const int MAXL(1e5);const int INF(0x3f3f3f3f);const int mod(1e9+7);int dir[4][2]= {{-1,0},{1,0},{0,1},{0,-1}};LL dp[20][20];void init(){ memset(dp,0); dp[0][0]=1; for(int i=1; i<=19; i++) { for(int j=0; j<=9; j++) { if(j==4) { for(int k=0; k<=9; k++) if(k!=9) dp[i][j]+=dp[i-1][k]; } else { for(int k=0; k<=9; k++) dp[i][j]+=dp[i-1][k]; } } }}int a[20];LL solve(LL n){ int len=0; while(n) a[++len]=n%10,n/=10; a[len+1]=0; LL ans=0; for(int i=len;i>=1;i--) { for(int j=0;j<a[i];j++) { if(a[i+1]==4&&j==9) continue; else ans+=dp[i][j]; } if(a[i+1]==4&&a[i]==9) break; } return ans;}int main(){ init(); cout<<dp[2][4]<<endl; int T; cin>>T; while(T--) { LL n; cin>>n; LL temp=solve(n+1); cout<<n+1-temp<<endl; }}