D - Bomb————数位dp

题目连接
会有很多做法,本菜渣现在只会这一种,如果你有什么好的做法请留下链接。 本菜渣也会持续更新

//带记忆数组

#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
int a[30];
long long dp[30][2][2][2];//下标 数位 four nine limit
long long dfs(int pos,int four,int nine, int limit)
{

    if( nine&&four&&pos== -1)return 1;//只有 前面有49才统计数
    else if(pos == -1)
    {
        return 0;
    }


    if(dp[pos][four][nine][limit]!= -1)return dp[pos][four][nine][limit];

    long long re = 0;



    int up;//上限
    up = limit?a[pos]:9;//判断上限为哪个



    for(int i = 0;i <= up;i++)//循环该位可能出现的数
    {
        if(four&&nine)re+= dfs(pos-1, true,true, limit&&a[pos] == i);//如果之前出现49 后面的数不管是什么 都符合题意
        else if(four)//上一个是4的情况
        {
            if(i == 9)re+=dfs(pos-1, true,true, limit&&a[pos] == i);//如果上一个是4这一个是9 后面不管是什么肯定符合题意
            else re+=dfs(pos-1, i == 4,false, limit&&a[pos] == i);// 否则 就重新判断 判断该数是否是4
        }
        else //上一个不是4的情况
        {
            re+=dfs(pos-1, i==4,false ,limit&&a[pos] == i);//重新判断该数是否是4
        }

    }



    return dp[pos][four][nine][limit] = re;
}

long long solve(long long x)//拆分函数
{
    memset(dp , -1, sizeof(dp));
    int len = 0;
    while(x)
    {
        int m = x%10;
        x/=10;
        a[len++] = m;
    }
    return dfs(len-1, false,false, true);


}
int main()
{

    int n;
    cin>>n;
    while(n--)
    {
        ll m;
        scanf("%lld", &m);
        cout<<solve(m)<<endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值