odd-even number

来源:互联网 发布:mysql回滚命令 编辑:程序博客网 时间:2024/05/20 20:45

这里写图片描述



数位dp,用 f[i][j][k][1/0]表示到第i位,数为j,奇偶连续了k位,1为满0为不满的方案数。然后f[i][j][k][] 就可以转移到下一位,假设为j1,如果 j1 与 j 同奇偶,那么直接转移到 f[i+1][j1][k][] 就好了,如果不同奇偶,那么就要判断一下 f[i][j][k][] 是否合法,及 j 和 k 不同奇偶性,就可以转移到 f[i+1][j1][1][],最后把所有合法的方案加起来就行了。



#include <stdio.h>#include <stdlib.h>#include <algorithm>#include <string.h>using namespace std;int a[20], b[20];char c;long long ans, n, m, f[20][20][20][5];long long calc(int a[]) {    long long sum = 0;    for (int len = 1; len < a[0]; len++) {        memset(f, 0, sizeof(f));        for (int i = 1; i <= 9; i++) f[1][i][1][0] = 1;        for (int i = 1; i < len; i++)            for (int j = 0; j <= 9; j++)                for (int k = 1; k <= i; k++) if (f[i][j][k][0] != 0) {                    for (int j1 = 0; j1 <= 9; j1++) {                        if (j1%2 == j%2) {                            f[i+1][j1][k+1][0] += f[i][j][k][0];                        } else {                            if (j%2 != k%2) {                                f[i+1][j1][1][0] += f[i][j][k][0];                            }                        }                    }                }        for (int j = 0; j <= 9; j++)            for (int k = 1; k <= len; k++) if (j%2 != k%2 && f[len][j][k][0] != 0)                sum += f[len][j][k][0];    }    memset(f, 0, sizeof(f));    for (int i = 1; i < a[1]; i++) f[1][i][1][0] = 1;    f[1][a[1]][1][1] = 1;    for (int i = 1; i < a[0]; i++)        for (int j = 0; j <= 9; j++)            for (int k = 1; k <= i; k++) {                /**/                if (f[i][j][k][0] != 0) {                    for (int j1 = 0; j1 <= 9; j1++) {                        if (j1%2 == j%2) {                            f[i+1][j1][k+1][0] += f[i][j][k][0];                        } else {                            if (j%2 != k%2) {                                f[i+1][j1][1][0] += f[i][j][k][0];                            }                        }                    }                }                /**/                if (f[i][j][k][1] != 0) {                    for (int j1 = 0; j1 < a[i+1]; j1++) {                        if (j1%2 == j%2) {                            f[i+1][j1][k+1][0] += f[i][j][k][1];                        } else {                            if (j%2 != k%2) {                                f[i+1][j1][1][0] += f[i][j][k][1];                            }                        }                    }                    if (a[i+1]%2 == j%2) {                        f[i+1][a[i+1]][k+1][1] += f[i][j][k][1];                    } else {                        if (j%2 != k%2) {                            f[i+1][a[i+1]][1][1] += f[i][j][k][1];                        }                    }                }            }    for (int j = 0; j <= 9; j++)            for (int k = 1; k <= a[0]; k++) if (j%2 != k%2)                sum += f[a[0]][j][k][0]+f[a[0]][j][k][1];    return sum;}bool check(int a[]) {    int state = a[1]%2, len = 1;    for (int j = 2; j <= a[0]; j++) {        if (a[j]%2 == state) len = len^1;        else {            if (state == len) return false;            state = a[j]%2;            len = 1;        }    }    if (state == len) return false;    return true;}int main() {    int tt;    scanf("%d", &tt);    for (int cases = 1; cases <= tt; cases++) {        scanf("%lld %lld", &n, &m);        a[0] = 0;        while (n > 0) {            a[++a[0]] = n%10;            n = n/10;        }        for (int i = 1; i <= a[0]/2; i++) swap(a[i], a[a[0]-i+1]);        b[0] = 0;        while (m > 0) {            b[++b[0]] = m%10;            m = m/10;        }        for (int i = 1; i <= b[0]/2; i++) swap(b[i], b[b[0]-i+1]);        ans = 0;        ans -= calc(a);        ans += calc(b);        if (check(a)) ans++;        printf("Case #%d: %lld\n", cases, ans);    }}
0 0
原创粉丝点击