UESTC 1307 WINDY数 (数位DP,基础)

题意:

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

思路:

  就是给连续的两位数字之间一些限制而已。主要还是放在推数量的问题上。相信很容易能写出转移方程,但是本题的问题在于前导零问题,不知道你是如何统计开头为0的,比如dp[i][0]表示什么?如果就要统计区间[0,10],输出的dp[2][0]会是8吗?(即02,03,04,05,06,07,08,09),其实你忘记了统计00和01,因为他们和前导0冲突了。所以想办法解决这个问题就行了。

  由于本题找不到提交源头了,码出来不保证正确性。

 1 //#include <bits/stdc++.h>
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <cmath>
 6 #include <map>
 7 #include <algorithm>
 8 #include <vector>
 9 #include <iostream>
10 #define pii pair<int,int>
11 #define INF 0x7f3f3f3f
12 #define LL long long
13 #define LL unsigned long long
14 using namespace std;
15 const double PI  = acos(-1.0);
16 const int N=10;
17 int dp[N][N], sum[N], bit[N+5];
18
19 void pre_cal()
20 {
21     sum[1]=10;
22     for(int i=0; i<N; i++) dp[1][i]=1;
23     for(int i=2; i<N; i++ ) //位数
24     {
25         sum[i]+=sum[i-1];
26         for(int j=1; j<N; j++)      sum[i]+=dp[i-1][j];//不含前导0
27         for(int j=0; j<N; j++)  //以j开头
28         {
29             for(int k=0; k<N; k++)  //下一个位以k开头
30                 if(abs(j-k)>=2)
31                     dp[i][j]+=dp[i-1][k];
32         }
33     }
34 }
35
36
37 int cal(int n)
38 {
39     memset(bit,0,sizeof(bit));
40     int len=0;
41     while(n)
42     {
43         bit[++len]=n%10;
44         n/=10;
45     }
46     int ans=sum[len-1], i=len;
47     for( ; i>0; i--)
48     {
49         for(int j=0; j<bit[i]; j++) //不能超过bit[i]
50             if( abs(bit[i+1]-j)>=2 )
51                 ans+=dp[i][j];
52         if( i<len && abs(bit[i+1]-bit[i])<2 )
53             break;      //上一位和这位已经构成非法
54     }
55     if(i==0)    ans++;
56     return ans;
57 }
58
59 int main()
60 {
61     //freopen("input.txt","r",stdin);
62     pre_cal();
63     int L, R;
64     while(~scanf("%d%d",&L,&R))
65         printf("%d\n",cal(R)-cal(L-1));
66     return 0;
67 }

代码

时间: 2024-10-12 18:59:57

UESTC 1307 WINDY数 (数位DP,基础)的相关文章

UESTC 250 windy数 数位dp

题目链接 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define mem1(a) memset(a, -1, sizeof(a)) 4 #define ll long long 5 int dp[20][20], digit[20], len; 6 ll dfs(int len, int pre, bool fp, bool first) { //first表示前面的数是否全部为0, pre是前一个数 7 if(!len) 8 re

USETC 250 windy数 数位DP

注意处理数字只有一位的情况(其实不用怎么处理)= = 简单数位DP #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include <cstdlib> #

bzoj 1026 windy数(数位DP)

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

[BZOJ 1026][SCOI 2009]windy数(数位DP)

题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1026 很基础的数位DP题,很早之前我就尝试做这题,不过当时我被这题吓死了,现在回过头做这题,感觉简单多了. 做这个题时我想到了POJ一道类似的组合数学的题,同样是按数位统计,有异曲同工之妙. 题目要求[a,b]区间上的windy数个数,我们可以转化成求[1,a]上的windy数个数-[1,b-1]上的windy数个数.题目转化成了求[1,x]上的windy数个数,我们就写个函数c

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

【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

bzoj 1026 [SCOI2009]windy数 数位dp

1026: [SCOI2009]windy数 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/problem.php?id=1026 Description windy定义了一种windy数.不含前导零且相邻两个数字之差至少为2的正整数被称为windy数. windy想知道,在A和B之间,包括A和B,总共有多少个windy数? Input 包含两个整数,A B. Output 一个整数.

[bzoj1006][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$ 位数