thafnhlong / hackerrank-storage

0 stars 0 forks source link

https://www.hackerrank.com/challenges/k-candy-store #47

Open thafnhlong opened 2 years ago

thafnhlong commented 2 years ago

Đây là bài toán tổ hợp lặp Có K tiền, bỏ K tiền vào N hộp, có bao nhiêu cách

= (K+N-1) C (N-1)

bài toán có kết quả lớn và chỉ lấy 9 chữ số cuối cùng :) ta không thể sử dụng field (modular calculation) .

Bản chất của tổ hợp là n! / (n-k)! / k!

ta sẽ dùng phương pháp rút gọn cổ điển :) . Sau đó sẽ ra con số lưu trữ được trong long.

ta có kết quả là : (n-k-1) ! / (n-1)! / k!

ta chọn (n-1)! rút gọn sẽ tương đương : [ n*(n+1)*(n+2)*...*(n-k-1) ] / [2*3*...k]

ta luôn chắc chắn phép chia trên là hết; vậy nên ta thực hiện rút gọn theo gcd(ts[i], ms[j]), lúc này ms=empty; thực hiện tính tích các phần tử trong ts và % cho 1e9;

int gcd(int a, int b){
    if(a==0) return b;
    return gcd(b%a, a);
}

int solve(int n, int k) {
    vector<int> ts, ms;
    int left = (n+k-1);
    int right = n-1;
    int l_r = k;

    for(int i=2;i<=l_r;++i){
        ms.push_back(i);
    }

    for(int i=right+1; i <= left;++i){
        ts.push_back(i);
    }

    long ret = 1;
    for(int i=0;i<ts.size();++i){
        for(int j=0;j<ms.size();++j){
            int cm = gcd(ts[i],ms[j]);
            if(cm > 1){
                ts[i]/= cm;
                ms[j]/= cm;
                if(ts[i] == 1) break;
            }
        }
        ret *= ts[i];
        ret %= 1000000000;
    }

    return ret;
}