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;
    }
  • 相关阅读:
    easyui源码翻译1.32--ValidateBox(验证框)
    easyui源码翻译1.32--TreeGrid(树形表格)
    easyui源码翻译1.32--Tree(树)
    easyui源码翻译1.32--TimeSpinner(时间微调)
    easyui源码翻译1.32--Tabs(选项卡)
    easyui源码翻译1.32--SplitButton(分割按钮)
    easyui源码翻译1.32--Slider(滑动条)
    easyui源码翻译1.32--SearchBox(搜索框)
    广度和深度-活在当下!
    IT人为了家庭和自己请保重自己~活在当下!
  • 原文地址:https://www.cnblogs.com/algorithms/p/2619186.html
Copyright © 2011-2022 走看看