数位DP bzoj1026

1026: [SCOI2009]windy数

Time Limit: 1 Sec  Memory Limit: 162 MB
Submit: 5809  Solved: 2589
[Submit][Status][Discuss]

Description

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

Input

  包含两个整数,A B。

Output

  一个整数

Sample Input

【输入样例一】
1 10
【输入样例二】
25 50

Sample Output

【输出样例一】
9
【输出样例二】
20

HINT

【数据规模和约定】

100%的数据,满足 1 <= A <= B <= 2000000000 。

代码:

 1 /*
 2 与上两道题类似,但不同的是本题要考虑首位非0。
 3 */
 4 #include<iostream>
 5 #include<string>
 6 #include<cstdio>
 7 #include<cmath>
 8 #include<cstring>
 9 #include<algorithm>
10 #include<vector>
11 #include<iomanip>
12 #include<queue>
13 #include<stack>
14 using namespace std;
15 int n,m;
16 int dp[13][10];
17 void init()
18 {
19     for(int i=0;i<10;i++)  //小于十的数单独计算
20     {
21         dp[1][i]=1;
22     }
23     for(int i=2;i<11;i++)
24     {
25         for(int j=0;j<10;j++)
26         {
27             for(int k=0;k<10;k++)
28             {
29                 if(abs(j-k)>=2)
30                 dp[i][j]+=dp[i-1][k];
31             }
32         }
33     }
34 }
35 int insum(int n)
36 {
37     int sum=0;
38     int cnt=0;
39     int c[13]={0};
40     while(n)
41     {
42         c[++cnt]=n%10;
43         n=n/10;
44     }
45     c[cnt+1]=0;
46     for(int i=1;i<cnt;i++)  //算前cnt-1位
47     {
48         for(int j=1;j<10;j++)   //j从1开始,前导非0
49         {
50             sum+=dp[i][j];
51         }
52     }
53     for(int i=1;i<c[cnt];i++)  //算最高位
54     {
55         sum+=dp[cnt][i];
56     }
57     for(int i=cnt;i>0;i--)  //最高位位已经算过了,从cnt-1位开始算
58     {
59         for(int j=0;j<c[i];j++)
60         {
61             if(abs(j-c[i+1])>=2)
62             sum+=dp[i][j];
63         }
64         if(abs(c[i]-c[i+1])<2)
65         break;
66     }
67     return sum;
68 }
69 int main()
70 {
71     while(cin>>n>>m)
72     {
73         memset(dp,0,sizeof(dp));
74         init();
75         cout<<insum(m+1)-insum(n)<<endl;
76     }
77     return 0;
78 }
时间: 2024-10-08 22:07:50

数位DP bzoj1026的相关文章

数位dp——BZOJ1026 Windy数

1026: [SCOI2009]windy数 Time Limit: 1 Sec  Memory Limit: 162 MB Description windy定义了一种windy数.不含前导零且相邻两个数字之差至少为2的正整数被称为windy数. windy想知道,在A和B之间,包括A和B,总共有多少个windy数? Input 包含两个整数,A B. Output 一个整数 Sample Input [输入样例一] 1 10 [输入样例二] 25 50 Sample Output [输出样例

[BZOJ1026][SCOI2009]windy数 解题报告|数位dp

Description windy定义了一种windy数.不含前导零且相邻两个数字之差至少为2的正整数被称为windy数. windy想知道,在A和B之间,包括A和B,总共有多少个windy数? 一直还是有点怕数位DP的...包括今天做这道简单的小题也花了很久的时间处理细节. 首先大体的思路非常明显,定义一个DP f[i,j]表示第i位放数字j有多少种方法,可以通过前一位的一些满足的数字推出这一位. 但是如何来解决在某个数A的范围内呢...? 并且一旦前面的没有取满,这一位都是可以0..9任意取

【luogu2657】【bzoj1026】 [SCOI2009]windy数 [动态规划 数位dp]

P2657 [SCOI2009]windy数 bzoj1026 一本通说这是一道数位dp模板题 emmmmm 就是逐位确定 f[i][j]表示填了i位数其最高位数字为j 然后就去求可能方案数 分为 不满足x的位数的严格小于x的全部情况 和x的位数相同 但最高位小于x的最高为的全部方案数 和x的位数相同 有一位比x的对应位数小的全部方案数 其余位数对应数字都相同(这是数位dp常用的一个性质:对于一个小于n的数 它从高位到低位一定会出现某一位上的数字小于n所对应这一位上的数字) PS 因为x不一定为

bzoj1026: [SCOI2009]windy数 数位dp

题目: http://www.lydsy.com/JudgeOnline/problem.php?id=1026 题意: Description windy定义了一种windy数.不含前导零且相邻两个数字之差至少为2的正整数被称为windy数. windy想知道, 在A和B之间,包括A和B,总共有多少个windy数? Input 包含两个整数,A B. Output 一个整数 思路: 数位dp,记忆化搜索. 1 #include <bits/stdc++.h> 2 3 using namesp

bzoj1026: [SCOI2009]windy数(数位dp)

1026: [SCOI2009]windy数 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 8203  Solved: 3687[Submit][Status][Discuss] Description windy定义了一种windy数.不含前导零且相邻两个数字之差至少为2的正整数被称为windy数. windy想知道, 在A和B之间,包括A和B,总共有多少个windy数? Input 包含两个整数,A B. Output 一个整数 Sample

【BZOJ-1026】windy数 数位DP

1026: [SCOI2009]windy数 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 5230  Solved: 2353[Submit][Status][Discuss] Description windy定义了一种windy数.不含前导零且相邻两个数字之差至少为2的正整数被称为windy数. windy想知道,在A和B之间,包括A和B,总共有多少个windy数? Input 包含两个整数,A B. Output 一个整数 Sample I

【bzoj1026】【SCOI2009】【windy数】【数位dp】

Description windy定义了一种windy数.不含前导零且相邻两个数字之差至少为2的正整数被称为windy数. windy想知道,在A和B之间,包括A和B,总共有多少个windy数? Input 包含两个整数,A B. Output 一个整数. Sample Input [输入样例一] 1 10 [输入样例二] 25 50 Sample Output [输出样例一] 9 [输出样例二] 20 HINT [数据规模和约定] 100%的数据,满足 1 <= A <= B <= 2

【bzoj1026】[SCOI2009]windy数 数位dp

题目描述 windy定义了一种windy数.不含前导零且相邻两个数字之差至少为2的正整数被称为windy数. windy想知道,在A和B之间,包括A和B,总共有多少个windy数? 输入 包含两个整数,A B. 输出 一个整数,表示答案 样例输入 [输入样例一] 1 10 [输入样例二] 25 50 样例输出 [输出样例一] 9 [输出样例二] 20 题解 数位dp 快联赛了重写了一下,发现以前写的太傻逼了= = 由于加一个数位的贡献只与最高位有关,因此设 $f[i][j]$ 表示 $i$ 位数

浅谈数位DP

在了解数位dp之前,先来看一个问题: 例1.求a~b中不包含49的数的个数. 0 < a.b < 2*10^9 注意到n的数据范围非常大,暴力求解是不可能的,考虑dp,如果直接记录下数字,数组会开不起,该怎么办呢?要用到数位dp. 数位dp一般应用于: 求出在给定区间[A,B]内,符合条件P(i)的数i的个数. 条件P(i)一般与数的大小无关,而与 数的组成 有关. 这样,我们就要考虑一些特殊的记录方法来做这道题.一般来说,要保存给定数的每个位置的数.然后要记录的状态为当前操作数的位数,剩下的