zoukankan      html  css  js  c++  java
  • 1026: [SCOI2009]windy数 (按位DP)

    定义windy数:相邻数字的差至少是2的数,例如10不是windy数,而13是windy数。求给定区间中有多少windy数。区间端点范围为 [1, 2000000000]

    dfs写法
    #include <stdio.h>
    #include <string.h>
    #define N 10
    int dp[N][N],digit[N];
    int dfs(int pos,int last,int z,int f)
    {
        if(pos==-1) return 1;
        if(z&&!f&&dp[pos][last]!=-1)    return dp[pos][last];
    
        int max=f?digit[pos]:9;
        int ret=0;
        if(z==0)
        {
            for(int i=0;i<=max;i++)
            {
                ret+=dfs(pos-1,i,i,f&&i==max);
            }
        }
        else
        {
            for(int i=0;i<=max;i++)
            {
                if((i-last)*(i-last)<4) continue;
                ret+=dfs(pos-1,i,1,f&&i==max);
            }
        }
        if(z&&!f)   dp[pos][last]=ret;
        return ret;
    }
    int cal(int x)
    {
        int pos=0;
        while(x)
        {
            digit[pos++]=x%10;
            x/=10;
        }
        return dfs(pos-1,0,0,1);
    }
    int main()
    {
        memset(dp,-1,sizeof(dp));
        int a,b;
        while(~scanf("%d%d",&a,&b)) printf("%d\n",cal(b)-cal(a-1));
        return 0;
    }
    递推写法
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    #define LEN 15
    char a[LEN],b[LEN];
    int n,m;
    int dp[LEN][10][2][2][2];       //第二维记录最后的数字,第三维记录状态是否合法,第四维记录该位是否是最高位,最后一维记录是否达到上界
    int nextstate(int cur,int last,int in)
    {
        if(cur==0 && abs(last-in)>=2)   return 0;
        return 1;
    }
    int nextflag1(int cur,int in,int max)
    {
        if(cur==1 && in==max)   return 1;
        if(cur==1 && in>max)    return -1;
        return 0;
    }
    int nextflag2(int cur,int in)
    {
        if(cur==1 && in==0) return 1;
        return 0;
    }
    int DP(char *s,int len)
    {
        memset(dp,0,sizeof(dp));
        dp[0][0][0][1][1]=1;
        for(int i=1;i<=len;i++)
            for(int last=9;last>=0;last--)
                for(int state=0;state<2;state++)
                    for(int flag1=0;flag1<2;flag1++)
                        for(int flag2=0;flag2<2;flag2++)
                            for(int in=0;in<10;in++)
                            {
                                int nxt=nextstate(state,last,in);
                                if(flag2==1)    nxt=0;
                                if(nextflag1(flag1,in,s[i]-'0')!=-1)
                                    dp[i][in][nxt][nextflag1(flag1,in,s[i]-'0')][nextflag2(flag2,in)]+=dp[i-1][last][state][flag1][flag2];
                            }
        int ret=0;
        for(int i=0;i<10;i++)   ret+=dp[len][i][0][0][0]+dp[len][i][0][1][0];
        return ret;
    }
    int main()
    {
        while(~scanf("%d%d",&n,&m))
        {
            n--;
            sprintf(a+1,"%d",n);
            sprintf(b+1,"%d",m);
            printf("%d\n",DP(b,strlen(b+1))-DP(a,strlen(a+1)));
        }
        return 0;
    }
  • 相关阅读:
    iOS tableViewCell自适应高度 第三发类库
    iOS 用 SDWebImage 清理图片缓存
    iOS JsonModel 的使用
    Objective-C语法之KVO使用
    iOS开发之 用第三方类库实现轮播图
    OS开发UI篇—使用UItableview完成一个简单的QQ好友列表
    iOS tableView 静态单元格的实现
    iOS沙盒目录结构解析
    ios开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布局
    AFNetworking 3.0.4 的使用
  • 原文地址:https://www.cnblogs.com/algorithms/p/2620431.html
Copyright © 2011-2022 走看看