hdu 3555 Bomb 經典數位DP

傳送門:Bomb

題目大意

給定一個整數N,求1~N中連續49的個數

解題思路

dp[i][0]表示長度爲i位,不包含49的個數
dp[i][1]表示長度爲i位,第一位是9的個數
dp[i][2]表示長度爲i位,包含49的個數

AC代碼

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
#include <iostream>
using namespace std;
typedef unsigned long long ULL;
const int MX = 69;
const int INF = 0x3f3f3f3f;
__int64 dp[MX][MX];

void init()
{
    memset(dp,0,sizeof dp);
    dp[0][0] = 1;
    for(int i=1; i<MX; i++)
    {
        dp[i][0] = dp[i-1][0]*10 - dp[i-1][1];//最高位有⑩種可能,但是要減去49開頭的
        dp[i][1] = dp[i-1][0];//最開頭是9後面的所有位不固定
        dp[i][2] = dp[i-1][2]*10 + dp[i-1][1];//前i-1位中包含49的並且加上i-1位中9開頭的
    }
}

__int64 solve(__int64 n)
{
    int len = 0,digit[MX],flag = 0;
    __int64 ans=0;
    while(n)
    {
        digit[++len] = n%10;
        n/=10;
    }
    digit[len+1] = 0;
    for(int i=len; i; i--)
    {
        ans+=dp[i-1][2]*digit[i];
        if(flag)  ans+=dp[i-1][0]*digit[i];
        if(!flag && digit[i]>4) ans += dp[i-1][1];
        if(digit[i+1]==4&&digit[i]==9) flag = 1;
    }
    return ans;
}
int main()
{
    __int64 T,N;
    init();
    cin>>T;
    while(T--)
    {
        cin>>N;
        cout<<solve(N+1)<<endl;
    }
    return 0;
}

使用DFS的方式

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int MX = 66;
__int64 dp[MX][MX][MX],digit[MX];

__int64 DFS(int pos,bool have,int last,int limit)
{
    if(pos==-1) return have;
    if(!limit && dp[pos][have][last]!=-1) return dp[pos][have][last];
    int endP = limit?digit[pos]:9;
    __int64 ans=0;
    for(int i=0;i<=endP;i++){
        if(last==4&&i==9) ans+=DFS(pos-1,true,i,limit&&(i==endP));
        else ans+=DFS(pos-1,have,i,limit&&(i==endP));
    }
    if(!limit) dp[pos][have][last] = ans;
    return ans;
}
__int64 solve(__int64 n)
{
    int len = 0;
    while(n){
        digit[++len] = n%10;
        n/=10;
    }
    return DFS(len,false,0,1);
}
int main()
{
    __int64 N;
    int T;
    cin>>T;
    while(T--){
        memset(dp,-1,sizeof dp);
        cin>>N;
        cout<<solve(N)<<endl;
    }
    return 0;
}
發佈了215 篇原創文章 · 獲贊 197 · 訪問量 50萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章