BNUT 1581 233333333 数位dp

来源:互联网 发布:黑客帝国3矩阵革命 编辑:程序博客网 时间:2024/05/19 02:21

BNUT 1581 233333333 数位dp

求n到m之间的搞笑数字,包含23或5的数字是搞笑数字,一个裸的数位dp。
dp[i][j][k]表示i位数最高位上为j时,是搞笑数字的个数(k=1),不是搞笑数字的个数(k=0)

代码:

/*************************************************************************    > File Name: e.cpp    > Author: gwq    > Mail: gwq5210@qq.com     > Created Time: 2015年05月01日 星期五 14时30分36秒 ************************************************************************/#include <cmath>#include <ctime>#include <cctype>#include <climits>#include <cstdio>#include <cstdlib>#include <cstring>#include <map>#include <set>#include <queue>#include <stack>#include <string>#include <vector>#include <sstream>#include <iostream>#include <algorithm>#define INF (INT_MAX / 10)#define clr(arr, val) memset(arr, val, sizeof(arr))#define pb push_back#define sz(a) ((int)(a).size())using namespace std;typedef set<int> si;typedef vector<int> vi;typedef map<int, int> mii;typedef long long ll;const double esp = 1e-5;#define N 20int dp[N][N][2], ans[N];int getans(int n){    int ans = 0;    char s[N];    sprintf(s, "%d", n);    int len = strlen(s);    int flag = 0;    for (int i = 0; i < len; ++i) {        int x = s[i] - '0';        for (int j = 0; j < x; ++j) {            ans += dp[len - i][j][1];            if (flag || (i != 0 && j == 3 && s[i - 1] == '2') || j == 5) {                ans += dp[len - i][j][0];            }            //printf("%d %d %d %d\n", len - i, j, dp[len - i][j][0], dp[len - i][j][1]);        }        //printf("\n");        if (s[i] == '5' || (s[i] == '3' && s[i - 1] == '2')) {            flag = 1;        }    }    return ans;}int main(int argc, char *argv[]){    clr(dp, 0);    dp[1][5][1] = 1;    dp[1][0][0] = 1;    dp[1][1][0] = 1;    dp[1][2][0] = 1;    dp[1][3][0] = 1;    dp[1][4][0] = 1;    dp[1][6][0] = 1;    dp[1][7][0] = 1;    dp[1][8][0] = 1;    dp[1][9][0] = 1;    for (int i = 2; i < N; ++i) {        for (int j = 0; j < 10; ++j) {            for (int k = 0; k < 2; ++k) {                for (int l = 0; l < 10; ++l) {                    if (k == 0) {                        if (j != 5 && (j != 2 || l != 3)) {                            dp[i][j][k] += dp[i - 1][l][0];                        }                    } else {                        dp[i][j][k] += dp[i - 1][l][1];                        if ((j == 2 && l == 3) || j == 5) {                            dp[i][j][k] += dp[i - 1][l][0];                        }                    }                }            }        }    }    int n, m;    while (scanf("%d%d", &n, &m) != EOF) {        if (n == 0 && m == 0) {            break;        }        int a = getans(m + 1);        int b = getans(n);        //printf("%d %d %d\n", a, b, a - b);        printf("%d\n", a - b);    }    return 0;}
0 0
原创粉丝点击