天天看點

BZOJ1026——windy數(數位DP)

題意:數位dp 限制條件是相鄰兩個數差至少為2 預處理dp數組 dp[i][j]表示i為高位且i位為數字j時滿足題意的種數。

因為要判斷最高位和前導0

當最高位枚舉的時候,可以是0,從前到後一直是0也可以,但是這個數是0,并且隻能算作一次

是以呢,記憶化的時候,需要一個bool變量,z

z為1,說明之前枚舉的高位已經有值了

z為0,說明之前枚舉的高位一直是0,如果一直是0,也不能在記憶化的時候直接傳回,跟flag的道理是一樣的

#include <iostream>

#include <cstdio>

#include <cstring>

#include <queue>

#include <cmath>

#include <algorithm>

#include <vector>

#include <map>

#include <string>

#include <stack>

using namespace std;

typedef long long ll;

#define PI 3.1415926535897932

#define E 2.718281828459045

#define INF 0x3f3f3f3f

#define mod 100000007

const int M=1005;

int n,m;

int cnt;

int sx,sy,sz;

int mp[1000][1000];

int pa[M*10],rankk[M];

int head[M*6],vis[M*100];

int dis[M*100];

ll prime[M*1000];

bool isprime[M*1000];

int lowcost[M],closet[M];

char st1[5050],st2[5050];

int len[M*6];

typedef pair<int ,int> ac;

//vector<int> g[M*10];

int dp[50][50];

int has[10500];

int month[13]= {0,31,59,90,120,151,181,212,243,273,304,334,0};

int dir[8][2]= {{0,1},{0,-1},{-1,0},{1,0},{1,1},{1,-1},{-1,1},{-1,-1}};

void getpri()

{

    ll i;

    int j;

    cnt=0;

    memset(isprime,false,sizeof(isprime));

    for(i=2; i<1000000LL; i++)

    {

        if(!isprime[i])prime[cnt++]=i;

        for(j=0; j<cnt&&prime[j]*i<1000000LL; j++)

        {

            isprime[i*prime[j]]=1;

            if(i%prime[j]==0)break;

        }

    }

}

struct node

{

    int v,w;

    node(int vv,int ww)

    {

        v=vv;

        w=ww;

    }

};

vector<int> g[M*100];

string str[1000];

int bit[50];

int dfs(int cur,int s,int e,int z){

    if(cur<0) return !z||s;//return 1;

    if(!e&&!z&&dp[cur][s]!=-1) return dp[cur][s];

    int endx=e?bit[cur]:9;

    int ans=0;

    for(int i=0;i<=endx;i++){

            if(!z&&abs(i-s)<2)continue;

        if(z&&!i) ans+=dfs(cur-1,i,e&&i==endx,1);

        else ans+=dfs(cur-1,i,e&&i==endx,0);

    }

    if(!e&&!z) dp[cur][s]=ans;

    return ans;

}

int solve(int n){

    int len=0;

    while(n){

        bit[len++]=n%10;

        n/=10;

    }

    return dfs(len-1,0,1,1);

}

int main()

{

    int i,j,k,t;

    int l,r;

    //while(~)

    //{

        scanf("%d%d",&l,&r);

        memset(dp,-1,sizeof(dp));

        printf("%d\n",solve(r)-solve(l-1));

    //}

    return 0;

}