Nonfibonacci numbers(数位dp)

Fibonacci numbers — well-known integer sequence, where F0=0, F1=1 and Fn=Fn−1+Fn−2 for n>1.

Lesha doesn’t like this sequence and all the numbers x, such that we can get positive Fibonacci number by crossing out several digits. For example, Lesha doesn’t like number 193, because it is possible to cross 9 out and get F6=13.

Your task is to find the number of integers from 0 to n which Lesha likes.

Input
The first line contains a single integer t — the number of test cases.

Each of the following t lines contains a single integer n — number, until which you have to count numbers which Lesha likes.

1≤t≤10
0≤n≤1018
Output
Print t lines, each of them should contain a single integer — the answer for the test case.

题意:如果某一个数列可以通过删除某些数位成为FIB数列,那么称为dislike。FIB数列也dislike。求[0,n]里like的数字。
解题思路:任何FIB数列都含{1,2,3,5,8}其中之一,只要数位dp跑一下就可以了。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
using namespace std;
#define LL long long
#define MT(a,b) memset(a,b,sizeof(a))
const int mod=10007;
const int maxn=2E5+5;
const int ONF=-0x3f3f3f3f;
const int INF=0x3f3f3f3f;
LL dp[20][3];
int num[20];
//sta=0 无fib sta=1 有fib
LL dfs(int pos,int sta,bool limit){
    if (pos==0) return (sta==0);
    if (!limit&&dp[pos][sta]!=-1) return dp[pos][sta];
    int up=limit?num[pos]:9;
    LL ans=0;
    for (int i=0;i<=up;i++){
        int NextSta=0;
//        if (i==0||i==1||i==2||i==3||i==5||i==8)
//            NextSta=1;
        if (sta==1) continue;
        if (sta==0){
            if (i==1||i==2||i==3||i==5||i==8)
                NextSta=1;
        }
        ans+=dfs(pos-1,NextSta,limit&&i==num[pos]);
    }
    if (!limit) dp[pos][sta]=ans;
    return ans;
}

LL solve(LL n){
    int cnt=0;
    while (n!=0){
        num[++cnt]=(int)n%10;
        n/=10;
    }
    return dfs(cnt,0, true);
}
int main (){
    int t;LL m;
    MT(dp,-1);
//    printf("%LLd\n",solve(2019));
    scanf ("%d",&t);
    while (t--){
        cin>>m;
        printf("%lld\n",solve(m));
    }
    return 0;
}
发布了33 篇原创文章 · 获赞 15 · 访问量 894

猜你喜欢

转载自blog.csdn.net/weixin_43925900/article/details/103949061