zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    bzoj 4066: 简单题 K-D树
    SAS获取最后一条观测到指定宏
    sas 获取字符串长度实例
    tomcat Error:NB:JAVA_HOME should point to a JDK not a JRE 解决方法
    ODBC数据源管理器-》系统DSN-》没有....Microsoft Access Driver(*mdb,*,accdb)
    SAS DATA ENCODING 解决odbc乱码问题
    sas 日期比较代码备忘
    sas transpose 代码备忘
    svn 红叉叉图标解决方法
    echart line 初始化隐藏legend
  • 原文地址:https://www.cnblogs.com/algorithms/p/2619186.html
Copyright © 2011-2022 走看看