数位DP 水~

来源:互联网 发布:海关数据库的企业代码 编辑:程序博客网 时间:2024/06/15 07:46

数位DP貌似很弱,先切水的练练手~

HDU2089:点击打开链接

输出区间里面没有连续62,没有4的数字个数.

#include <bits/stdc++.h>using namespace std;long long n, m;int bit[11], l;int dp[11][2];int dfs (int pos, bool f1, bool f2) {//当前的位数 前一个数是不是6 是不是可以取到9    if (pos == 0)        return 1;    if (f2 && dp[pos][f1] != -1) {        return dp[pos][f1];    }    int Max = (f2 ? 9 : bit[pos]), ans = 0;     for (int i = 0; i <= Max; i++) {        if (i == 4 || (f1 && i == 2))            continue;        ans += dfs (pos-1, i==6, f2 || i<Max);    }    if (f2)        dp[pos][f1] = ans;    return ans;}long long f (long long num) {    l = 0;    while (num) {        bit[++l] = num%10;        num /= 10;    }    return dfs (l, 0, 0);}int main () {    memset (dp, -1, sizeof dp);    while (cin >> n >> m && n+m) {        cout << f (m)-f (n-1) << endl;    }    return 0;}


HDU3555:点击打开链接

1到n中没有连续49的数字个数.

同样

#include <bits/stdc++.h>using namespace std;typedef unsigned long long ull;ull n;int bit[11], l;ull dp[22][2];ull dfs (int pos, bool f1, bool f2) {//当前的位数 前一个数是不是4 是不是可以取到9    if (pos == 0)        return 1LL*1;    if (f2 && dp[pos][f1] != -1) {        return dp[pos][f1];    }    int Max = (f2 ? 9 : bit[pos]);    ull ans = 0;    for (int i = 0; i <= Max; i++) {        if (f1 && i == 9)            continue;        ans += dfs (pos-1, i==4, f2 || i<Max);    }    if (f2)        dp[pos][f1] = ans;    return ans;}long long f (long long num) {    l = 0;    while (num) {        bit[++l] = num%10;        num /= 10;    }    return dfs (l, 0, 0);}int main () {    //cout << (((ull)1<<63)-1) << endl;    memset (dp, -1, sizeof dp);    int t;    cin >> t;    while (t--) {        cin >> n;        cout << n-f (n)+1 << endl;    }    return 0;}


UVA11361:点击打开链接

求所有位数和以及本身模k等于0的数的个数.

很相似,dfs的时候记录到当前位之前所有位数模k的余数m1和到当前位之前后面全部补0的余数m2,

转移方程就是dp(pos,m1,m2) = sigma {dp(pos-1, (m1-i)%k, (m2-i*10^pos-1)%k)}.

#include <bits/stdc++.h>using namespace std;long long n, m, mod;int bit[11], l;long long dp[12][111][111];#define pow Powlong long pow[13];long long dfs (int pos, long long m1, long long m2, bool f2) {//当前的位数 所有的数位和模m余m1 后面的数字模m余m2 是不是可以取到9    if (pos == 0) {        if (m1 == 0 && m2 == 0)            return 1;        return 0;    }    if (f2 && dp[pos][m1][m2] != -1) {        return dp[pos][m1][m2];    }    long long Max = (f2 ? 9 : bit[pos]);    long long ans = 0;    for (long long i = 0; i <= Max; i++) {        ans += dfs (pos-1, (m1-i+mod)%mod, ((m2-i*pow[pos-1])%mod+mod)%mod, f2 || i < Max);    }    if (f2)        dp[pos][m1][m2] = ans;    return ans;}long long f (long long num) {    l = 0;    while (num) {        bit[++l] = num%10;        num /= 10;    }    if (l*9 < mod) {        return 1;//只能是0    }    return dfs (l, 0, 0, 0);}int main () {    pow[0] = 1;    for (long long i = 1; i <= 11; i++) pow[i] = pow[i-1]*10;    int t;    cin >> t;    while (t--) {        cin >> n >> m >> mod;        memset (dp, -1, sizeof dp);        cout << f (m) - f(n-1) << endl;    }    return 0;}







0 0