zoukankan      html  css  js  c++  java
  • Atcoder681 Typical DP Contest E.数 数位dp

    写什么递归....非递归多好写

    令$f[i][j]$表示前$i$位的和在模$d$意义下为$j$的方案数,然后转移即可

    复杂度$O(10000 * 100 * 10)$

    注意非递归建议高位摆第$n$位...

    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    #define ri register int
    #define rep(io, st, ed) for(ri io = st; io <= ed; io ++)
    #define drep(io, ed, st) for(ri io = ed; io >= st; io --)
    
    const int sid = 10050;
    const int pid = 105;
    const int mod = 1e9 + 7;
    
    char s[sid];
    int d, n, f[sid][pid];
    
    inline void inc(int &a, int b) { a += b; if(a >= mod) a -= mod; }
    inline int inv(int a) { return (d - (a % d)) % d; }
    
    void Solve() {
        f[0][0] = 1;
        rep(i, 1, n)
            rep(j, 0, 9) rep(k, 0, d - 1)
                inc(f[i][(k + j) % d], f[i - 1][k]);
    
        int ret = 0;
        rep(i, 1, n - 1) rep(j, 1, 9) 
            inc(ret, f[i - 1][inv(j)]); 
        rep(i, 1, s[n] - 1) 
            inc(ret, f[n - 1][inv(i)]);
            
        int sum = s[n] % d;
        drep(i, n - 1, 1) {
            rep(j, 0, s[i] - 1)
                inc(ret, f[i - 1][inv(sum + j)]);
            sum = (sum + s[i]) % d;
        }
        if(!sum) ret ++;
        printf("%d
    ", ret);
    }
    
    int main() {
        scanf("%d", &d);
        scanf("%s", s + 1);
        n = strlen(s + 1); reverse(s + 1, s + n + 1);
        rep(i, 1, n) s[i] = s[i] - '0'; 
        Solve();
        return 0;
    }
  • 相关阅读:
    HDU 4069 Squiggly Sudoku
    SPOJ 1771 Yet Another NQueen Problem
    POJ 3469 Dual Core CPU
    CF 118E Bertown roads
    URAL 1664 Pipeline Transportation
    POJ 3076 Sudoku
    UVA 10330 Power Transmission
    HDU 1426 Sudoku Killer
    POJ 3074 Sudoku
    HDU 3315 My Brute
  • 原文地址:https://www.cnblogs.com/reverymoon/p/9932526.html
Copyright © 2011-2022 走看看