HDU3555Bomb(记忆化搜索)

来源:互联网 发布:端口号是什么 编辑:程序博客网 时间:2024/05/16 04:38

题目与不要62相似,数位dp

#include <map>#include <set>#include <stack>#include <queue>#include <cmath>#include <ctime>#include <vector>#include <cstdio>#include <cctype>#include <cstring>#include <cstdlib>#include <iostream>#include <algorithm>using namespace std;#define INF 0x3f3f3f3f#define inf -0x3f3f3f3f#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define mem0(a) memset(a,0,sizeof(a))#define mem1(a) memset(a,-1,sizeof(a))#define mem(a, b) memset(a, b, sizeof(a))typedef long long ll;ll dp[25][3];//dp[i][0]    有i位且都不含49//dp[i][1]   有i位且第i位为9//dp[i][2]   有i位且都含49void init(){    mem0(dp);    dp[0][0]=1;    for(int i=1;i<=22;i++){        dp[i][0]=dp[i-1][0]*10-dp[i-1][1];        dp[i][1]=dp[i-1][0];        dp[i][2]=dp[i-1][2]*10+dp[i-1][1];    //    cout<<"PPPP"<<i<<"PPPP"<<dp[i][0]<<"PPPP"<<dp[i][1]<<"PPP"<<dp[i][2]<<endl;    }}__int64     solve(__int64 n){    int len=0,a[100];    while(n){        a[++len]=n%10;        n/=10;    }    a[len+1]=0;    __int64 ans=0;    int flag=0;//    for(int i=len;i>=1;i--)//        cout<<"PPPP"<<a[i]<<endl;    for(int i=len;i>=1;i--){        ans+=dp[i-1][2]*a[i];        if(flag)            ans+=dp[i-1][0]*a[i];   //不要忘记乘以a[i]!         if(!flag&&a[i]>4)            ans+=dp[i-1][1];        if(a[i]==9&&a[i+1]==4)            flag=1;    }    return ans;}int main(){    init();    int t;    __int64 n;    scanf("%d",&t);    while(t--){        scanf("%I64d",&n);        printf("%I64d\n",solve(n+1));    }    return 0; }
#include<bits/stdc++.h>using namespace std;typedef long long ll;int bit[100];ll dp[20][3];ll dfs(int p,int have,int lim){    int have_x;    if(p<=0)        return (have==2);    if(lim!=1&&dp[p][have]!=-1)        return dp[p][have];    int num= lim?bit[p]:9;              //lim为0表示下一位没有限制,lim为1表示下一位有限制    ll ans=0;    for(int i=0;i<=num;i++){            //have=0表示末尾既不是9也不是4        have_x=have;                    //have=1表示末尾是4        if(have==1&&i!=4)               //have=2表示存在4和9连在一起            have_x=0;        if(have==1&&i==9)            have_x=2;        if(have==0&&i==4)            have_x=1;        ans+=dfs(p-1,have_x,lim&&(num==i));        //printf("%d %d %I64d\n",p,i,ans);    }    if(!lim)        dp[p][have]=ans;    return ans;}void work(ll n){    int len=0;    while(n){        bit[++len]=n%10;        n/=10;    }    bit[len+1]=0;    printf("%I64d\n",dfs(len,0,1));}int main(){    ll n;    int t;    memset(dp,-1,sizeof(dp));    scanf("%d",&t);    while(t--){        scanf("%I64d",&n);        work(n);    }    return 0;}
0 0
原创粉丝点击