C♯の勉強

C♯4.0 で TopCoder の過去問を解きます。

TopCoder SRM597: LittleElephantAndSubset

public class LittleElephantAndSubset {
    int mod = 1000000007;

    void enumeratePattern(int[] pattern, int N, int used = 0, long current = 0) {
        if (current > N) return;
        if (current > 0) {
            pattern[used]++;
        }

        for (int d = 0; d <= 9; d++) {
            if (current == 0 && d == 0) continue;
            if ((used & (1 << d)) != 0) continue;
            long next = current * 10 + d;
            enumeratePattern(pattern, N, used | (1 << d), next);
        }
    }

    public int getNumber(int N) {
        int[] pattern = new int[1 << 10];
        enumeratePattern(pattern, N);

        int all = (1 << 10) - 1;
        var dp = new long[1 << 10];
        dp[0] = 1;

        for (int i = 0; i < (1 << 10); i++) {
            int remain = i ^ all;
            for (int j = remain; j > 0; j = (j - 1) & remain) {
                if (i >= j) continue;
                dp[i | j] += dp[i] * pattern[j];
                dp[i | j] %= mod;
            }
        }

        return (int)dp.Skip(1).Aggregate((a, b) => (a + b) % mod);
    }
}