Skip to content

Instantly share code, notes, and snippets.

@KirillLykov
Created July 27, 2019 20:15
Show Gist options
  • Save KirillLykov/e09a6f74ef1bfb7171ebff7b7081391f to your computer and use it in GitHub Desktop.
Save KirillLykov/e09a6f74ef1bfb7171ebff7b7081391f to your computer and use it in GitHub Desktop.
Interesting DP problem from AC

Interesting problem on dynamic programming from atcoder. Given a string in the format "(|?)+" find how many number can be formed such that the reminder of the division of each of this numbers by 13 gives exactly 5.

So lets define function dp[x][y] to be count of such numbers for prefix of length x and reminder y. For example, for 1?2 dp[2][5] will mean the count of such numbers for substring 1? and the reminder 5.

The interesting part is the transition. It uses implicit difinition.

for (all prevReminder)
  dp[i+1][ (prevReminder * 10 + curDigit)%13 ] += dp[i][prevReminder]
#include <bits/stdc++.h>
using namespace std;
const size_t M = 1e9 + 7;

int main(int,char**) {
    ios_base::sync_with_stdio(0); cin.tie(NULL);
    string s;
    cin >> s;
    
    int n = s.size();
    
    // dp(x, y) = how many such numbers
    // where x is the prefix length, y is reminder by 13
    vector< vector<size_t> > dp(n+1, vector<size_t>(13, 0));
    dp[0][0] = 1;
    
    
    for (int i = 0; i < n; ++i) {
        if (s[i] != '?') {
            int curDigit = s[i] - '0';
            for (int prevRem = 0; prevRem < 13; ++prevRem) {
                int curRem = (10*prevRem + curDigit)%13;
                dp[i+1][curRem] = (dp[i+1][curRem] + dp[i][prevRem])%M;
            }
        } else {
            // curDigit may be any 0..9
            for (int curDigit = 0; curDigit < 10; ++curDigit) {
                for (int prevRem = 0; prevRem < 13; ++prevRem) {
                    int curRem = (10*prevRem + curDigit)%13;
                    dp[i+1][curRem] = (dp[i+1][curRem] + dp[i][prevRem])%M;
                }
            }
        }
    }
    cout << dp[n][5] << endl;
    return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment