• HDOJ 3555 Bomb (按位DP)


    题目大意:求1到n中有多少个数含“49”

    第一次接触按位DP,参考了别人的题解。

    第一个代码运行速度快些(31ms),但状态的转移的分析比较麻烦,第二个代码要慢些(125ms),但code比较方便。

    View Code
    #include <stdio.h>
    #include <string.h>
    #define LEN 22
    typedef __int64 LL;
    char s[LEN];
    LL dp[LEN][3][2];
    int next(int cur,int in)
    {
        if(cur==2 || cur==1&&in==9) return 2;
        return in==4;
    }
    LL DP(char s[],int len)
    {
        memset(dp,0,sizeof(dp));
        dp[0][0][1]=1;
        for(int i=1;i<=len;i++)
        {
            dp[i][0][0]=9*dp[i-1][0][0]+8*dp[i-1][1][0];
            dp[i][1][0]=dp[i-1][0][0]+dp[i-1][1][0];
            dp[i][2][0]=10*dp[i-1][2][0]+dp[i-1][1][0];
    
            for(int j=0;j<s[i]-'0';j++)
            {
                dp[i][next(0,j)][0]+=dp[i-1][0][1];
                dp[i][next(1,j)][0]+=dp[i-1][1][1];
                dp[i][next(2,j)][0]+=dp[i-1][2][1];
            }
    
            dp[i][next(0,s[i]-'0')][1]+=dp[i-1][0][1];
            dp[i][next(1,s[i]-'0')][1]+=dp[i-1][1][1];
            dp[i][next(2,s[i]-'0')][1]+=dp[i-1][2][1];
        }
        return dp[len][2][0]+dp[len][2][1];
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%s",s+1);
            printf("%I64d\n",DP(s,strlen(s+1)));
        }
        return 0;
    }
    View Code
    #include <stdio.h>
    #include <string.h>
    #define LEN 22
    typedef __int64 LL;
    char s[LEN];
    LL dp[LEN][3][2];
    int nextstate(int cur,int in)
    {
        if(cur==2 || cur==1&&in==9) return 2;
        return in==4;
    }
    int nextflag(int cur,int in,int max)
    {
        if(cur==1 && in==max)   return 1;
        if(cur==1 && in>max)    return -1;
        return 0;
    }
    LL DP(char s[],int len)
    {
        memset(dp,0,sizeof(dp));
        dp[0][0][1]=1;
        for(int i=1;i<=len;i++)
        {
            for(int state=0;state<3;state++)
            {
                for(int flag=0;flag<2;flag++)
                {
                    for(int j=0;j<10;j++)
                    {
                        if(nextflag(flag,j,s[i]-'0')==-1)   continue;
                        dp[i][nextstate(state,j)][nextflag(flag,j,s[i]-'0')]+=dp[i-1][state][flag];
                    }
                }
            }
        }
        return dp[len][2][0]+dp[len][2][1];
    }
    int main()
    {
        freopen("in.txt","r",stdin);
        int t;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%s",s+1);
            printf("%I64d\n",DP(s,strlen(s+1)));
        }
        return 0;
    }
  • 相关阅读:
    一文解读AI芯片之间的战争 (转)
    一文解读ARM架构 (转)
    一文解读云计算 (转)
    一文解读裸金属云 (转)
    一文解读发布策略 (转)
    C#使用OracleDataReader返回DataTable
    centos8平台上php7.4的生产环境配置
    centos8安装php7.4
    centos8安装java jdk 13
    docker的常用操作之二:docker内无法解析dns之firewalld设置等
  • 原文地址:https://www.cnblogs.com/algorithms/p/2619186.html
Copyright © 2020-2023  润新知