bzoj 1026

1026: [SCOI2009]windy数

Time Limit: 1 Sec  Memory Limit: 162 MB
Submit: 7861  Solved: 3539
[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 。

思路:dp[i][j]表示第i位为j的方案

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 int dp[15][10];
 5 
 6 void init(){
 7     for(int i=0;i<=9;i++) dp[1][i]=1;
 8     for(int i=2;i<=13;i++){
 9         for(int j=0;j<=9;j++){
10             for(int k=0;k<=9;k++){
11                 if(abs(j-k)>=2)
12                     dp[i][j]+=dp[i-1][k];
13             }
14         }
15     }
16 }
17 
18 int hh(int x){
19     int b[20];
20     int len=0;
21     while(x){
22         b[++len]=x%10;x/=10;
23     }
24     int sum=0;
25     for(int i=1;i<len;i++){//i位数满足的总和
26         for(int j=1;j<=9;j++) sum+=dp[i][j];
27     }
28     for(int i=1;i<b[len];i++)//len位但是最高位小于b[len].
29         sum+=dp[len][i];
30     for(int i=len-1;i>=1;i--){//对于前面所有位不变的方案//
31         for(int j=0;j<b[i];j++){
32             if(abs(b[i+1]-j)>=2)
33                 sum+=dp[i][j];
34         }
35         if(abs(b[i]-b[i+1])<2)//如果这两位相差不符合,前面的数字就固定不了了,break;
36             break;
37     }
38     return sum;
39 }
40 
41 int main(){
42     init();
43     int n,m;
44     scanf("%d%d",&n,&m);
45     cout<<hh(m+1)-hh(n)<<endl;
46 }

 

posted on 2017-07-28 10:53  hhhhx  阅读(...)  评论(... 编辑 收藏

导航