Solution to a problem P2657 [[SCOI2009] windy number]

First we look at the topic

windy defines a number windy. Without leading zeros and adjacent to at least the difference between two numbers is called a positive integer number windy.

1- observation subject, determine the type of

Keywords can be drawn from the title: without leading zeros and is adjacent to two numbers, the range of data observed: 100% data satisfies 1 <= A <= B <= 2000000000. We can clearly see that this is a problem digit dp template.

2- Release state transition equation

Because the conditions subject to very clear, we can get: we should set up a two-dimensional array, where one dimension is used to represent the i-th bit, and the other dimension is represented on the bit number is j (0 <= j <= 9) (when we move the array of dynamic programming must have a close relationship with the answers, but also clever use of conditions on the subject, must have locality during every step of the transfer.)

Dp tree features: a press-bit processing features, the issues addressed are generally larger issue of digital data, and a link between each adjacent bits. Dp and the tree can not be directly after the answer dp partially completed, the transfer is generally relatively simple, but the calculation is very complicated answer.

3- answer calculated (assuming pre-process ends dp)

The number of such practice usually ask certain number within a range, because a lot of trouble so we calculate the interval is calculated by the method of interval upper bound minus the lower bound, so that only 1-n calculate how much the situation, relatively simple . First, we calculate the number of results is shorter than the length of the upper bound len (since the length is smaller than the upper bound of the number smaller than a certain upper bound, it can be 1-9 all accumulate, because it can not start from scratch without leading zeros ) followed by the upper bound of the same but the length and the most significant bit position than the most upper bounds of small (may accumulate all)

The last is about the highest-bit computing with the upper bound of the same number as the highest level has been determined, because the current position of undetermined value directly affects the next, so we have to push down from the peak: len-1 to 1, from 1 to enumerate the upper bound on the bit value -1 (because if the enumeration of the number equal to the upper bound of the bit number, the next bit value will be limited so tired can not join the answer) each bit of this accumulation, and returns the cumulative result has been calculated.

The final answer is the result of subtracting the upper bound lower bound.

Finally, the Code

#include<iostream>
#include<cstdio>
#include<math.h>
#include<cstring>
using namespace std;
int f[101][11]={0},n,m,a[11]={0};
void before(){
    for(int i=0;i<=9;i++) f[1][i]=1;
    for(int i=2;i<=32;i++){
        for(int j=0;j<=9;j++){
            for(int k=0;k<=9;k++) if(abs(j-k)>=2) f[i][j]+=f[i-1][k];
        }
    }
}
int solve(int num){
    int ans=0,len=0;
    memset(a,0,sizeof(a));
    while(num) a[++len]=num%10,num/=10; 
    for(int i=1;i<=len-1;i++){ //长度小于len的都可以累加 
        for(int j=1;j<=9;j++) ans+=f[i][j];
    }
    for(int i=1;i<=a[len]-1;i++) ans+=f[len][i];//长度等于len但是最高位小于a[len]的可以累加
    for(int i=len-1;i>=1;i--){
        for(int j=0;j<=a[i]-1;j++){
            if(abs(j-a[i+1])>=2) ans+=f[i][j]; //如果这个数和前一个数不合法则不累加 
        }       
        if(abs(a[i]-a[i+1])<2) break; //如果其中两数的值一定小于2,则没有长度为len最高位相同的情况 
    }
    return ans;
}
int main()
{
    before();
    cin>>n>>m;
    cout<<solve(m+1)-solve(n)<<endl;
}

Guess you like

Origin www.cnblogs.com/tianbowen/p/11286422.html