kmjp's blog

競技プログラミング参加記です

LeetCode Weekly Contest 128 : 1015. Numbers With Repeated Digits

これ問題文ひどくない…?
https://leetcode.com/contest/weekly-contest-128/problems/numbers-with-repeated-digits/

問題

正整数Nが与えられる。
N以下の正整数で、各桁に登場する数字で複数回登場するものが1種以上あるのは何通りか。

解法

自分は複数回登場しない数字を数え、Nから引いた。
あとは良くあるDPで、現在見ている桁の位置、登場済みの数字のbitmask、上位の桁がNと一致しているか、leading zeroになりうるか、の4種の状態を持って桁DP。

int memo[11][1<<10][2][2];


class Solution {
public:
	ll N;
	int hoge(int d,int mask,int lim,int lead,ll p10) {
		if(d==-1) return 1;
		if(memo[d][mask][lim][lead]>=0) return memo[d][mask][lim][lead];
		
		ll ret=0;
		
		int i;
		int ma=10;
		if(lim) ma=N/p10%10;
		FOR(i,ma) {
			if(lead&&i==0) {
				ret+=hoge(d-1,mask,0,1,p10/10);
			}
			else if((mask&(1<<i))==0) {
				ret+=hoge(d-1,mask^(1<<i),0,0,p10/10);
			}
		}
		if(ma<10) {
			if(lead==1 && ma==0) {
				ret+=hoge(d-1,mask,1,1,p10/10);
			}
			else if((mask&(1<<ma))==0) {
				ret+=hoge(d-1,mask|(1<<ma),1,0,p10/10);
			}
		}
		return memo[d][mask][lim][lead]=ret;
	}
    int numDupDigitsAtMostN(int N) {
        MINUS(memo);
        this->N=N;
        return N+1-hoge(10,0,1,1,10000000000LL);
    }
};

まとめ

repeatedは連続するかどうか迷った人が多数いた様子。
英語ネイティブなら間違えないのかな。