dp[ どれを使ったか ][ これまでの余り ]
- int divS(string s, int K)
- {
- vector<int> v;
- for (int i = 0; i < s.size(); ++i) {
- v.push_back(s[i] - '0');
- }
- for (int i = 0; i + 1 < v.size(); ++i) {
- v[i + 1] += (v[i] % K) * 10;
- }
- return v.back() % K;
- }
- lli gcd(lli a, lli b)
- {
- return b ? gcd(b, a % b) : a;
- }
- class WickedTeacher {
- public:
- string cheatProbability(vector <string> ns, int K)
- {
- const int N = 15 + 1;
- const int BIT = 1 << N;
- const int M = 101;
- char buff[1000];
- int D[N][M];
- for (int i = 0; i < ns.size(); ++i) {
- for (int j = 0; j < K; ++j) {
- sprintf(buff, "%d", j);
- string t = string(buff) + ns[i];
- D[i][j] = divS(t, K);
- }
- }
- static lli dp[BIT][M];
- fill(&dp[0][0], &dp[BIT][0], 0);
- dp[0][0]= 1;
- for (int bit = 0; bit < (1 << ns.size()); ++bit) {
- for (int m = 0; m < M; ++m) {
- if (dp[bit][m] == 0) continue;
- for (int i = 0; i < ns.size(); ++i) {
- if (bit & (1 << i)) continue;
- dp[bit | (1 << i)][D[i][m]] += dp[bit][m];
- }
- }
- }
- lli q = 0;
- lli p = dp[(1 << ns.size()) - 1][0];
- for (int m = 0; m < K; ++m) {
- q += dp[(1 << ns.size()) - 1][m];
- }
- if (p == 0 && q == 0) return "0/0";
- lli r = gcd(max(p, q), min(p, q));
- p /= r;
- q /= r;
- string P, Q;
- sprintf(buff, "%lld", p);
- P = string(buff);
- sprintf(buff, "%lld", q);
- Q = string(buff);
- return P + "/" + Q;
- }
- };