bzoj1026: [SCOI2009]windy数

http://www.lydsy.com/JudgeOnline/problem.php?id=1026

 

数位DP

如果前一位填的是0,

0是前导0,下一位可以随便填

0不是前导0,下一位不能填1

为避免这种情况

枚举位数,强制不出现前导0

#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

int dp[12][12];

int a[11];

int LEN;

int dfs(int dep,int num,bool lim)
{
    if(!lim && dp[dep][num]!=-1) return dp[dep][num];
    if(!dep) return 1;
    int up= lim ? a[dep] : 9,tmp=0; 
    for(int i=0;i<=up;++i)
    {
        if(dep==LEN && !i) continue;
        if(abs(i-num)<2) continue;
        tmp+=dfs(dep-1,i,lim && i==up);
    }
    if(!lim) dp[dep][num]=tmp;
    return tmp;
}

int solve(int n)
{
    if(!n) return 0;
    int len=0;
    while(n)
    {
        a[++len]=n%10;
        n/=10;
    }
    int sum=0;
    for(int i=1;i<len;++i) 
    {
        LEN=i;
        sum+=dfs(i,11,0);
    }
    LEN=len; 
    sum+=dfs(len,11,1);
    return sum;
}

int main()
{
    int a,b;
    scanf("%d%d",&a,&b);
    memset(dp,-1,sizeof(dp));
    printf("%d\n",solve(b)-solve(a-1));
}
View Code

 

或者是记录有无前导零这个状态

#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

int dp[12][12][2];

int a[11];

int LEN;

int dfs(int dep,int num,bool lim,bool zero)
{
    if(!lim && dp[dep][num][zero]!=-1) return dp[dep][num][zero];
    if(!dep) return !zero;
    int up= lim ? a[dep] : 9,tmp=0; 
    for(int i=0;i<=up;++i)
    {
        if(abs(i-num)<2 && !zero) continue;
        tmp+=dfs(dep-1,i,lim && i==up,zero && !i);
    }
    if(!lim) dp[dep][num][zero]=tmp;
    return tmp;
}

int solve(int n)
{
    if(!n) return 0;
    int len=0;
    while(n)
    {
        a[++len]=n%10;
        n/=10;
    }
    return dfs(len,11,1,1);
}

int main()
{
    int a,b;
    scanf("%d%d",&a,&b);
    memset(dp,-1,sizeof(dp));
    printf("%d\n",solve(b)-solve(a-1));
}
View Code

 

 

1026: [SCOI2009]windy数

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

posted @ 2017-11-26 08:05  TRTTG  阅读(235)  评论(0编辑  收藏  举报