leetcode 1015. Numbers With Repeated Digits
題意:統計1-N中,滿足每個位置都不同的數有幾個。
思路:數位DP。通過一個1<<10的mask表示當前這個數,1-9哪些數被用了。
比賽的時候,一直想通過一個dfs直接找到不重複的數,一直不對。
賽後發現,別人都是通過一個dfs找重複的數,然後總個數減去。
class Solution {
public:
int numDupDigitsAtMostN(int N) {
int sum = N + 1;
memset(bit, 0, sizeof(bit));
memset(dp, 0, sizeof(dp));
int k = 0;
while (N) {
bit[++k] = N % 10;
N /= 10;
}
return sum - dfs(k, true, 0);
}
//不重複數的個數
int dfs(int len, bool limit, int mask) {
if (len == 0)
return 1;
if (!limit && dp[len][mask][limit]) return dp[len][mask][limit];//記憶化部分
int maxn = limit ? bit[len] : 9;//求出最高可以枚舉到哪個數字
int ans = 0;
for (int i = 0; i <= maxn; i++) //當前位
{
if ((mask&(1 << i)) == 0)
{
if (mask == 0 && i == 0)
ans += dfs(len - 1, limit && i == maxn, mask);//有前導0,所以0不能統計,不更新mask
else
ans += dfs(len - 1, limit && i == maxn, mask | (1 << i));//更新mask
}
}
if (!limit) dp[len][mask][limit] = ans;//如果沒有限制,代表搜滿了,可以記憶化,否則就不能
return ans;
}
private:
int bit[19];
int dp[19][1 << 10][2];
};