BZOJ 1026 windy数

来源:互联网 发布:怎样开淘宝店视频教程 编辑:程序博客网 时间:2021/01/17 11:51

简单数位dp。数组为三维,分别记录第几位,前一位数字,和状态。相同位不同数字的结果不一样,一开始只开了两维,结果导致出错。和之前的数位dp不一样,本题是考虑两位之间的关系,而不是固定的考虑某一两位数字。比如1 的下一位可以有7种状态,而9 的下一位有8种。无比dt的调了好久。。。

#include <cstdio>#include <algorithm>#include <cstring>#include <cstdlib>#include <iostream>using namespace std;#define LL long long#define INF 1000000000#define N 1000char a[20], b[20];int len;int dp[20][10][2];int dfs(int id, int s, int pre, bool f){    if(id >= len){        if(s == 1)return 1;        else return 0;    }    if(!f && dp[id][pre][s] != 0)return dp[id][pre][s];    int edge = f ? (a[id] - '0') : 9;    int ans = 0;    for(int i = 0; i <= edge; i++){        if(s == 0){            if(i == 0)ans += dfs(id + 1, 0, 0, f && i == edge);            else ans += dfs(id + 1, 1, i, f && i == edge);        }        else if(s == 1){            if(abs(i - pre) >= 2)ans += dfs(id + 1, 1, i, f && i == edge);        }    }    return f ? ans : (dp[id][pre][s] = ans);}int main(){    while(scanf("%s %s", a, b) !=EOF){        memset(dp, 0, sizeof(dp));        len = strlen(a);        int suma = dfs(0, 0, 0, true);        int f = 1;        for(int i = 0; i < len - 1; i++){            if(abs(a[i] - a[i + 1]) < 2){f = 0; break;}        }        strcpy(a, b);        len = strlen(a);        memset(dp, 0, sizeof(dp));        int sumb = dfs(0, 0, 0, true);        sumb -= suma;        sumb += f;        printf("%d\n", sumb);    }    return 0;}


0 0