zoukankan      html  css  js  c++  java
  • 【dp】B-number

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3652

    题解:先预处理([0,0][1,1],[2,2]....[0,9],[10, 19],[20,29]......[900000000, 1000000000]  区域中 有子串13 (用1表示)余数为0,1,2.。。12的个数。以及 无子串13(用0表示)余数为0,1,2,3.。。12 的个数。

    四维数组dp【一共多少位数】【最高位的数】【是否含有子串13】【余数】 例如  dp[4][1][1][0] 表示 (【1000,2000))(四位, 最高位数为1), 子串中含有13, 且余数为0的个数。

     dp[a][b][c][d] 

    当求a = 2时必须 a=1的元素都已知,例如 求[20, 29)中含有13, 余数为3的个数。 即 dp【2】【2】【0】【3】 ,由于 [20, 29)可看做 20 + x(0—9)。而20 % 13 = 7, 只需找余数为9. 则 sum( dp【1】【j】【0】【9】)(j= 0,1,2.。。。9)。

    需注意的是 当b = 1 时, 由于在低一位上有3,  所以这种情况要分开求。

    /***Good Luck***/
    #define _CRT_SECURE_NO_WARNINGS
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <string>
    #include <algorithm>
    #include <stack>
    #include <map>
    #include <queue>
    #include <vector>
    #include <set>
    #include <functional>
    #include <cmath>
    #include <numeric>
    
    #define Zero(a) memset(a, 0, sizeof(a))
    #define Neg(a)  memset(a, -1, sizeof(a))
    #define All(a) a.begin(), a.end()
    #define PB push_back
    #define inf 0x3f3f3f3f
    #define inf2 0x7fffffffffffffff
    #define ll long long
    using namespace std;
    //#pragma comment(linker, "/STACK:102400000,102400000")
    void get_val(int &a) {
        int value = 0, s = 1;
        char c;
        while ((c = getchar()) == ' ' || c == '
    ');
        if (c == '-') s = -s; else value = c - 48;
        while ((c = getchar()) >= '0' && c <= '9')
            value = value * 10 + c - 48;
        a = s * value;
    }
    const int maxn = 20;
    int dp[maxn][maxn][2][maxn];
    int n;
    
    void change1(int i, int j, int m) {
        for (int k = 0; k <= 1; ++k)
        for (int kk = 0; kk <= 12; ++kk) {
            dp[i][j][1][(kk - m + 13) % 13] += dp[i - 1][3][k][kk];  
        }
    }
    
    void change2(int i, int m,int j, int jj) {
        for (int k = 0; k <= 1; ++k)
        for (int kk = 0; kk <= 12; ++kk) {
            dp[i][j][k][(kk + m) % 13] += dp[i - 1][jj][k][kk];
        }
    }
    void init() {
        Zero(dp);
        int w = 10, m;
        dp[0][0][0][0] = 1;
        for (int i = 0; i <= 10; ++i) dp[1][i][0][i] = 1;
        for (int i = 2; i <= 9; ++i) {
            for (int j = 0; j <= 9; ++j) {
                
                for (int jj = 0; jj <= 9; ++jj) {
                    m = (j * w) % 13;
                    if (j == 1 && jj == 3) {
                        m = (jj * w / 10 )% 13;
                        change1(i, j, m);
                    } else
                        change2(i, m, j, jj);
                }
            }
            w *= 10;
        }
    }
    
    int cal(int n1) {
        if (n1 == 1000000000) return 5993844;
        char ch[15];
        Zero(ch);
        int i = 1;
        int flag = -1;
        int ret = 0;
        while (n1) {
            ch[i++] = n1 % 10 + '0';
            n1 /= 10;
        }
        for (int j = i - 1; j > 0; --j) {
            if (ch[j] == '1' && ch[j - 1] == '3') {
                flag = j - 1;
                break;
            }
        }
        n1 = n / 10;
        int w = 1;
        for (int j = 1; j <= i; ++j) {
            for (int jj = 0; jj < ch[j] - '0'; ++jj) {
                int t = (n1 * 10 ) * w % 13;
                if (jj == 3 && ch[j + 1] == '1') {
                    t = (n1 / 10 * 100) * w % 13;
                    ret += dp[j][0][0][(13 - t) % 13] + dp[j ][0][1][(13 - t) % 13];
                    continue;
                }
                if (flag > j) {
                    ret += dp[j][jj][0][(13 - t) % 13] + dp[j][jj][1][(13 - t) % 13];
                } else {
                    ret += dp[j][jj][1][(13 - t) % 13];
                }
            }
            w *= 10;
            n1 /= 10;
        }
        if (n % 13 == 0 &&  flag != -1) ret++;
        return ret;
    }
    int main() {
        //freopen("data.out", "w", stdout);
        //freopen("data.in", "r", stdin);
        //cin.sync_with_stdio(false);
        init();
        while (cin >> n) {
            cout << cal(n) << endl;
        }
        return 0;
    }
  • 相关阅读:
    [2019 CSP-S赛前集训] [CF1037D] Valid BFS?
    [2019 CSP-S赛前集训] [洛谷P1613] 跑路
    [2019 CSP-S赛前集训] [洛谷P1967] 货车运输
    [洛谷博客] 我的洛谷博客内容搬运
    终于开通了博客
    Qt Creator 添加arm版本的qmake时的问题
    U盘挂载问题
    段错误解决办法
    printf %m
    使用pthread_create()创建线程
  • 原文地址:https://www.cnblogs.com/yeahpeng/p/3993467.html
Copyright © 2011-2022 走看看