알고리즘 : 순열 및 조합

조합 수

조합론의 존재는 구성, 구조 및 계산 문제의 특정 조건을 만족하는 오브젝트의 이산 세트를 연구하는 것이다. 이론적 수는 좁은 조합 적 수학은 기초 연구, 연구는 주로 특정 조건 순열과 계산 문제를 충족이다. 조성물 식을 카운팅하는 카운팅 원리 카운트를 포함하는 계산 방법.

조합 수의 기초

추가 원리

N = m_1과 m_2 + + ... + : 하나의 목적은 첫 번째 경우에 대해 N 개의 상이한 경우에 달성 내가 수 있다면 \ [다른 방법 m_i \\있어서 다음의 총 개수 N이있다 m_n = \ sum_ {I = 1} ^ N m_i \]

상기 조건 중 각각 하나의 목적은 다른 조건들에 의존하지 않고 달성 될 수있다 달성하기 위해, 두 개의 방법 중 어느 경우에 고유하다.

곱셈 원리

N 단계 이후, 공정 k에 대한 후 상이한 방식 \\있어서의 총 수 N이 m_k 경우 \ [목표를 달성 : N = m_1과는 \ 시간 \ 시간 ... \ 시간 m_2을 m_n = \ prod_가 ^ {I} = 1 N m_i \]

그 중,이, 토폴로지 수있는 단계 사이의 관계이지만, 각 단계는 필수적이며, 각 단계에서 다른 단계에 어떻게 영향을 미치는지 여부를 선택할.

포함-배타 원리

가장 중요한 것은 결합 카운트 반복되지 않고 , 놓치지 마세요 . 그러나 이중 계산의 많은 정상적인 상황, 또는 분류 토론에서 특정 조건의 누락에서 발생 항상있다. 그런 다음 우리는 통합과 배제해야합니다. 포함-배타 원리의 기본 개념이있다 : 각 단계는 다음과 올바른 사용을 반복 할 수없는 놓치지 마세요 이유가 있기 때문에, 경우의 수 모두에 와서하고 일부 중복 계산을 제외 반복 간주되지 않습니다.

화학식 :
\ [집합 S가 유한 집합이다 A_I \ SUBSETEQ S, I \ N에 ^ +, 다음 \\ | \ bigcup_ {I = 1 } ^ N A_I | = \ sum_ {K = 1} ^ N (-1 ) ^ {K-1} \ sum_ {1 \ 르 i_1 <I_2 <... <i_k \ 르 N} | A_ {i_1} \ bigcap A_ {I_2} \ bigcap ... \ bigcap A_ {i_k} | \ ]
포함될 배제 수학적 귀납법에 의해 증명하고, 수식 세트 동작의 다음의 기본 방정식 (드 모르 강의 식)에 의해 얻어 질 수있다
. \ [\ 윗줄 {. \ bigcup_ 1} = {I} ^ N-A_I = \ bigcap_ 1 = {I} ^ N- \ {윗줄 A_I \\} \ 윗줄 {\ {bigcap_ I = 1} ^ N A_I} = \ bigcup_ ^ {I} = 1 n \ 윗줄 A_I {} \]

조합 카운트 기본 수식

배열 번호 화학식

N 개의 상이한 요소 촬영 중 m (m ≦ N) 요소는 일렬로 배열에서, n은 다른 원소 찍은 m 요소들의 공지 된 배열 (요소의 순서를 고려 나타났다). m의 순열의 수, 즉 배열 번호 배열의 총 개수는 N 개의 상이한 요소들로부터 추출 요소 (순열의 수)라고한다. 배열 번호 심볼 P (순열) 또는 A (배열)에 의해 나타내었다.
\ [A_n는 m ^ (P_n ^ m)을 수득 프로그램 번호에 해당 요소로부터 제거 배치 된 m (순서가 고려되어야한다)을 나타낸다. \\ A_n ^ m = N (N -1) ... (㎚ + 1) = {N! \ 위에 (㎚)!} \]

확장

\ [{정렬} 1. 고리 치환 베긴 \라고도 원형 배열은 내측, N = {m 이상 A_n가 ^ m \} \\ 및 2 내지 N 원소의 고리 치환을 구성하는 순열 N m 삭제 소자의 수를 의미 . K 클래스로 N 원소 i 번째 요소의 수는 소자 N = {N! \ 위에 \ prod_ {I = 1} ^ K n_i!} \\\ 단부 (n)의 순열의 수는 이때 n_i이고 ] \ {} 배향

조합 식의 숫자

N 개의 상이한 요소 촬영 m (m ≦ N) 중 임의의 요소 그룹 (순서가 고려되지 않은) 구성에서, m 요소들의 알려진 조합은 N 개의 상이한 요소 촬영. 조합의 총 개수는 m의 조합의 수는 N 개의 상이한 요소들로부터 추출 소자 (조합 번호)를 호출 즉, 조합의 수이다. 조합의 수는 기호 C로 나타낸 :
\ [C_n가 ^ m의 m은 n 개의 요소로 구성되는 그룹으로부터 얻어진 (순서에 관계없이) 제거 된 프로그램 수를 나타내며, 이항 계수 (_n ^ m)으로 표현 될 수있다. \\ C_n ^ {m = A_n ^ m 이상 m \!} = {N! \ 위에 (㎚)! M!} \]

확장

\ [K 희토류 원소는, 각 타입의 요소들의 무제한 C_ {K + m-1} ^ m \ 대한 m에서 이들 요소의 조합의 수이다]

속성의 조합의 수

\ [{} 정렬 시작 및 1.C_n \ ^ m = C_n ^ {} 내지 \\ 및 2.mC_n ^ m = nC_ {N-1} ^ {m-1} \\ 및 3. 组合 数 递推 式: C_n ^ m = C_ {N-1} ^ {m-1} + C_ {N-1} ^ m \\ 및 제 二项式 系数 : \ sum_ {I = 0} ^ N ^ C_n 난을 C_n = ^ 0 ^ C_n + 1 + ... + C_n ^ N = 2 ^ N \\ 및 \ 공간 \ 공간 C_n ^ 0 ^ 2 + C_n ... + C_n ^ = 1 + C_n ^ 3 + ... = 2 ^ {N-1} \\ 및 5.C_m ^ m + m + C_ {1} ^ m + ... + m + C_ {N} ^ m = C_ {m + N + 1} ^ {m + 1} \\ 및 6.C_n ^ 0 + C_ {N + 1} ^ 1 + ... + C_ {N} ^ m + m = C_ {N + m + 1} ^ m \\ 및 2N} {7.C_ ^ 2 = 2C_n ^ 2 + N ^ 2 \\ \ 단부 정렬 {} \]

错排 공식

문제의 잘못된 행은 수학의 고전적인 문제 중 하나의 조합입니다. 지그재그 형상 오차, 즉 : N 원소로 이루어진 하나 개의 구성, 각 소자는 원래의 위치에,이 배열은 지그재그 배치라고 원래 안 재정렬. 번호 태거 N 개의 엘리먼트의 어레이는 D (n)은 다음과 같이 표시된다 :
\ [\를가 {정렬 = 왼쪽} & D (n)은 \\ = n \ 좌측 [시작 - {1 \ OVER1 {1 \ over0를}.!.! } + {1 \ OVER2!} ... + {\ 좌측 \\ = N (-1 ^ n \ 오른쪽) \ 위에 N!} \ 오른쪽]! \ cdot \ sum_ {I = 0} ^ {N ( ! -1) ^ I \ 통해 I } = n \ cdot \ sum_ {내가 = 2} ^ {N (-! 1) ^ I \ 통해 I} = \\ \ 왼쪽 [{n \ E 위에}! +0.5 \ 오른쪽 (둥근 도입 {1 \ 위에 E} 확장형) \ {단부 정렬} \]

공통 기술 결합 계수

번들 법

질문 특정 요소가 연속적이어야 때, 함께 고려 전체 및 기타 요소로, 전체 넣어. 참고 : 전체 내부 순서가있다.

보간 방법

인접한 특정 요소를 필요로하지 않는 경우, 다른 구성 요소는 제 늘어서 있고, 그 다음에 필요한 보이드 인접하지 않은 요소 또는 요소의 양단 적절히 배치되었다.

파티션 방법

동일한 소자의 여러 패킷의 문제를 해결하는데, 만약 상기 패킷의 목적을 달성하기 위해, 그룹 당 적어도 하나 개의 원소로, 그룹 마이너스 행 이들 원소 중 하나의 "스페이서"의 수에 삽입 될 수 필요한.
\ [예 : N 공 박스 M, 각 상자는 비어 있지 거기 C_ {N-1} ^ { m-1} 프로그램 종류, 박스가 필요하지 않은 경우 비어는, m의 도입 될 수 \\ 공의 볼을 해결하기 위해 분할 방법의 각 박스의 각각으로부터 제거하고, 상기 프로그램 번호 C_ {N + m-1} ^ {m-1} \]

  1. A, B, C, D, E A, B가 함께 얼마나 많은 STATION 총을 서 있지 않는 행, 다섯?
    \ [보간 방법 : 우리가 C, D, E 프로그램 번호 A_3 ^ 3 정렬 줄 고려할 수 있도록로, B는 함께 참을 수 \\ 3 명 사 개 격차,을 떠난 후 정리, 승산 원리에 따라 보간 B, 프로그램 번호 A_4 ^ 2 프로그램의 총 수 A_3 ^ 3 \ cdot A_4 ^ 2 . \]

  2. A, B, C, D, E , A는, B가 함께 얼마나 많은 STATION 총을 서 있어야 행, 다섯?
    \ [번들 방법하십시오 때문에, B는 전체로서 본 \\ 전반적인 후 동일 처리 "묶음"우리는 단순히 A, B 넣어 함께서야와 C, D, E. 내부 A에 대한, B의 프로그램 A_2 ^ 2의 수 \\ 외부 프로그램 번호 A_4 ^ 4. 총 계획 : A_2 ^ 2 \ cdot A_4 ^ 4. \]

  3. 테이블 세 프로그램의 프로그램은 동일한 상대하기 위해 다음 몇 가지 프로그램으로, 두 개의 새로운 프로그램을 추가를 유지하고,있다?
    \ [{정렬} 시작 및 번들 + 보간법 방법에서 \ \\ 및 두 가지 경우, 1 \\ 및 두 개의 새 프로그램 인접한 세 개의 프로그램은 네 개의 비어있는 다음의 내부 서열을 고려 전체 프로그램을 원자 C_4 ^ 1 \ cdot A_2 ^ 2 ]. \\ & 2 개 방송 개의 비 인접 2-4 빈 보간 프로그램, 프로그램 번호 A_4 ^ 2] \\ 및 다음 프로그램 즉 C_4 ^ 1 \ cdot의 총 개수 A_2 ^ 2 + 2 ^ A_4. \ 단부 정렬 {} \]

  4. 세 가지 다른 상자에 8 개의 동일한 공, 각 상자는 적어도 하나의 공, 몇 가지 방법을 넣어하는 데 필요한?
    \ [방법 분리기 : 행 여덟 볼, 볼 (7) 사이의 갭의 수, 지금 우리가 두 세퍼레이터 세퍼레이터 7 \\ 개의 공극을 삽입 할 수 있다고 가정 공으로가 분할 될 수있다 세 박스, 프로그램 번호 C_7 ^ (2)에 대응하는 3 기의 시퀀스. \]

  5. (6397 HDU)가 이탈리아 그 : N 개의 세는, m은 (K)가 0에서 선택된 ~ N-1 행의 수 m이되도록 그 동일하고 동일한 개수 m 될 수 K,만큼 상이한의 구성 그것은 할 수 있습니다. 얼마나 많은 준비의 총을 찾는 것은 질문의 의미를 충족합니다.

\ [N-m 구형 카트리지 유사한 문제는 빈 카세트 일 수있다. 관계없이 크기 제한 번호, 프로그램의 총 수 K + C_ {m-1} ^ {m-1}. \\ 일련 번호 (X), 거기 X_1 X_2 + + ... + x_m = K이다 \\ 순서 x_i로부터 y_i = + 1, 세퍼레이터 분석 하였다 y_1 y_2 + + + ... + m = y_m 케이. \\하지만 크기가 N 내의 항목의 수를 제한 할 수 있고, 그 다음이 고려 :이어서, 이상인 X N가 우리 제한적 열거 이후 내가 수 \\, 즉, 번호 m이 존재한다고 가정 이때 숫자 체계이다 : \\ C_m ^ I \ cdot C_ {K + m-1-I \ 시간 N} ^ {m-1}, 해당 분석 : \\ X_1 '+ X_2'+ ... + x_m 'KI = \ N 번. \\ 마지막으로, 포함 배제 홀수 플러스도 답을 줄일 수. \]

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int maxn = 2e5 + 100;
const int mod = 998244353;

ll inv[maxn], F[maxn], Finv[maxn];

void init() {
    inv[1] = 1;
    for(int i = 2; i < maxn; i++)
        inv[i] = (mod - mod / i) * inv[mod % i] % mod;
    F[0] = Finv[0] = 1;
    for(int i = 1; i < maxn; i++) {
        F[i] = F[i - 1] * i % mod;
        Finv[i] = Finv[i - 1] * inv[i] % mod;
    }
}

ll C(ll n, ll m) {
    if(n < 0 || m < 0 || m > n) return 0;
    return F[n] * Finv[m] % mod * Finv[n - m] % mod;
}

int main() {
    int t, n, m, k;
    init();
    cin >> t;
    while(t--) {
        cin >> n >> m >> k;
        ll ans = 0;
        for(int i = 0; i * n <= k; i++) {
            int r = C(m, i) * C(k - i * n + m - 1, m - 1) % mod;
            if(i & 1) ans = (ans - r + mod) % mod;
            else ans = (ans + r) % mod;
        }
        cout << ans << endl;
    }
    return 0;
}
  1. K의 (우바 10,943)는 음이 아닌 정수의 수요를 초과 할 수 없음 이러한 프로그램과 n의 수를 추가하지 않는다. 방법 분리기 카세트를 비울 수 있습니다. 데이터 범위가 상대적으로 작기 때문에 그래서 모든 사전 DP, O (1)의 직접 질의 결과.

    #include<bits/stdc++.h>
    using namespace std;
    const int mod = 1e6;
    int n, k, dp[111][111]; // dp[i][j]表示用j个数使得和为i的方案数
    int main() {
     for (int i = 1; i <= 100; i++) {
         dp[i][1] = 1;
         dp[1][i] = i;
     }
     for (int i = 2; i <= 100; i++)
         for (int j = 2; j <= 100; j++)
             dp[i][j] = (dp[i - 1][j] + dp[i][j - 1]) % mod;
     while (cin >> n >> k && (n|k)) { 
            cout << dp[n][k] << endl;
     }
        return 0;
    }
  2. (CF GYM 100,548)은 N m, 인접하는 다른 색의 요구, 및 K로 정확하게 컬러의 수를 이용하여 그린 꽃 색 배열된다. 프로그램 %의 1E9 + 7의 수를 찾는.

    분석 : 포함과 배제의 + 곱셈 원리.
    \ [프로그램 번호 C_m ^ K {정렬} 시작 \ 및 m은 선택적으로 K 색의 제 1 색으로부터 선택되고; \\ 및 승산 원리 : 제 꽃에 대해, K의 선택은 각각의 후속 위해 존재 꽃, \\은 없다, 즉 단지 (K-1)의 선택을 보장하기 위해 반복 프로그램 넘버 \\ K \ 배 (K-1) ^ {N-1}. 그러나 \\ 및 색을 사용하여 이번 결함 회전율 번호 (k) 프로그램의 수가 제외 포함 배제 원리를 필요로 포함한다. \\ 및 그린 I (K) 색상이 고려에서 촬영 프로그램 번호 C_K ^ I \ cdot P (p -1) ^ {N-1}, 홀수 발수 결합능 환원도 증가가 그려 질 수있다 : \\ 및 전체 프로그램 수 N = C_m ^ K \ cdot K (K-1) ^ {N-1} + \ sum_ {내가 = 2} ^ {K-1} (- 1) ^ iC_k ^ I \ cdot I (I -1) ^ {N-1} \\ 및 명백하게 표준 공정 다음 역 요소 조합 급격한 전력의 수를 사용할 필요가있다. \ 단부 정렬 {} \]

    #include <iostream>
    using namespace std;
    typedef long long ll;
    
    const int mod = 1e9 + 7;
    const int maxn = 1000010;
    
    ll ans, inv[maxn], F[maxn], Finv[maxn];
    
    ll qpow(ll a, ll b) {
        ll ans = 1;
        while(b) {
            if(b & 1) ans = (ans * a) % mod;
            b >>= 1; a = (a * a) % mod;
        }
        return ans;
    }
    
    void init() {
        inv[1] = 1;
        for(int i = 2; i < maxn; i++)
            inv[i] = (mod - mod / i) * inv[mod % i] % mod;
        F[0] = Finv[0] = 1;
        for(int i = 1; i < maxn; i++) {
            F[i] = F[i - 1] * i % mod;
            Finv[i] = Finv[i - 1] * inv[i] % mod;
        }
    }
    
    ll C(ll n, ll m) {
        if(n < 0 || m < 0 || m > n) return 0;
        return F[n] * Finv[m] % mod * Finv[n - m] % mod;
    }
    
    int main() {
     init();
     int t, kase = 0;
        cin >> t;
        while (t--) {
            cin >> n >> m >> k;
            ans = C(m, k) * k % mod * qpow(k - 1, n - 1) % mod;
            ll sign = 1;
            for(ll i = 2; i < k; i++) {
             ans = (ans + C(k, i) * i % mod * qpow(i - 1, n - 1) % mod * sign + mod) % mod;
             sign = -sign;
            }
            cout << "Case #" << ++kase << ": " << ans << endl;
        }
        return 0;
    }

추천

출처www.cnblogs.com/Li-F/p/11894612.html