zoukankan      html  css  js  c++  java
  • 【BZOJ1026】【SCOI2009】windy数

    Description

    windy定义了一种windy数。不含前导零且相邻两个数字之差至少为2的正整数被称为windy数。 windy想知道,在A和B之间,包括A和B,总共有多少个windy数?

    Input

    包含两个整数,A B。

    Output

    一个整数。

    Sample Input1

    1 10

    Sample Output1

    9

    Sample Input2

    25 50

    Sample Output2

    20

    Hint

    100%的数据,满足$ 1leq A leq B leq 2*10^{9}$ 。

    Solution

    数位DP,用(f_{i,j})表示i位数,最高位为j的情况,容易得出DP方程为(f_{i,j}=Sigma_{k} f_{i-1,k} (|k-j| leq 2)).

    Code

    #include <stdio.h>
    #define MN 15
    #define R register
    int a,b,f[MN][MN],q[MN];
    void init(){
    	for (R int i=0; i<10; ++i) f[1][i]=1;
    	for (R int i=2; i<11; ++i)
    		for (R int j=0; j<10; ++j)
    			for (R int k=0; k<10; ++k)
    				if (j-k>1||k-j>1)
    					f[i][j]+=f[i-1][k];
    }
    int get(int x){
    	if (!x) return 0;R int res=0,k=0;
    	while(x){q[++k]=x%10;x/=10;}
    	for (R int i=1; i<k; ++i) 
    		for (R int j=1; j<10; ++j)
    	    	res+=f[i][j];
    	for (R int i=1; i<q[k]; ++i)
    		res+=f[k][i];
    	for (R int i=k-1; i; --i){
            for (R int j=0; j<q[i]; ++j)
            	if (j-q[i+1]>1||q[i+1]-j>1)
            		res+=f[i][j];
    		if (q[i+1]-q[i]>1||q[i]-q[i+1]>1){
    			if (i==1) ++res;
    			continue;
    		}break;
        }return res;
    }
    int main(){
    	init();scanf("%d %d",&a,&b);
    	printf("%d",get(b)-get(a-1)); 
    	return 0;
    }
    
  • 相关阅读:
    19 C#循环语句的跳过和中断 continue和break
    18 C#中的循环执行 for循环
    一种绝对提高开发水平的方法(推荐英语)
    大数据知识普及
    全链路压测压测报告
    QuickSearch快排
    二分查找
    算法
    基于领域驱动设计的业务中台架构设计
    【科普】Scrum——从橄榄球争球到敏捷开发
  • 原文地址:https://www.cnblogs.com/Melacau/p/BZOJ1026.html
Copyright © 2011-2022 走看看