Bomb HDU - 3555

http://acm.hdu.edu.cn/showproblem.php?pid=3555

dp[i][0]代表[i+1,n-1]位上没出现过49且第i+1位上的数不是4

dp[i][1]代表[i+1,n-1]位上没出现过49但第i+1位上的数是4

dp[i][2]代表[i+1,n-1]位上已出现过49

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn=50;

ll dp[maxn][3];
int bit[maxn];

ll dfs(int pos,int pre,int sta,int limit)
{
    ll res;
    int up,i,tmp;
    if(pos==-1){
        return sta==2;
    }
    if(!limit&&dp[pos][sta]!=-1){
        return dp[pos][sta];
    }
    if(limit) up=bit[pos];
    else up=9;
    res=0;
    for(i=0;i<=up;i++){
        if(i==4){
            tmp=max(1,sta);
        }
        else if(i==9){
            if(pre==4) tmp=2;
            else tmp=sta;
        }
        else{
            if(sta==2) tmp=2;
            else tmp=0;
        }
        res+=dfs(pos-1,i,tmp,limit&&i==bit[pos]);
    }
    if(!limit) dp[pos][sta]=res;
    return res;
}

ll solve(ll val)
{
    int n;
    n=0;
    while(val>0){
        bit[n++]=val%10;
        val/=10;
    }
    return dfs(n-1,-1,0,1);
}

int main()
{
    ll val;
    int t;
    memset(dp,-1,sizeof(dp));
    scanf("%d",&t);
    while(t--){
        scanf("%lld",&val);
        printf("%lld\n",solve(val));
    }
    return 0;
}

其实可以反面考虑 即求不含49的数

#include <bits/stdc++.h>
using namespace std;
#define ll long long

ll dp[30][2];
ll num[30];

ll solve(ll n);
ll dfs(int step,int pre,int sta,int lim);

int main()
{
    ll n,sum;
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%lld",&n);
        printf("%lld\n",n-solve(n)+1);
    }
    return 0;
}

ll solve(ll n)
{
    int i,p;
    i=0;
    while(n>0)
    {
        num[++i]=n%10;
        n/=10;
    }
    memset(dp,-1,sizeof(dp));
    return dfs(i,0,0,1);
}

ll dfs(int step,int pre,int sta,int lim)
{
    ll ans;
    int up,i;
    if(step==0) return 1;
    if(lim==0&&dp[step][sta]!=-1) return dp[step][sta];
    if(lim==1) up=num[step];
    else up=9;
    ans=0;
    for(i=0;i<=up;i++)
    {
        if(pre==4&&i==9) continue;
        ans+=dfs(step-1,i,i==4,lim==1&&i==num[step]);
    }
    if(lim==0) dp[step][sta]=ans;
    return ans;
}

猜你喜欢

转载自blog.csdn.net/sunyutian1998/article/details/88681959
今日推荐