워커 연습 게임 1 트리 dp + dfs 시퀀스

제목 링크

문제 풀이:


처음에는 트리 DP가 밑에서 위로 업데이트되는 것을 생각했는데 아들이 많을 때 상황이 너무 많아서 고려할 수가 없었어요.
dfs 순서에 따라 나무의 점을 하나하나 염색할 수 있습니다.이렇게 한 노드 x를 염색할 때, 그의 아버지 노드는 이미 염색되었다.정의 상태 dp[i][j]dp[i][j]dp[i][j]는 dfs 서열의 전 ii 노드를 jj j 색상으로 염색하는 몇 가지 방안이 있습니까?ii i 결점 염색의 경우 다음 두 가지 옵션이 있습니다.
4
  • 이전 i-3-1i-1i-3 1개의 결점을 사용한 색을 선택한다.그럼 이 결점에서 염색할 수 있는 색깔은 아버지가 염색한 색깔이 틀림없다.앞의 어느 결점과 염색이 같든 경로가 아버지의 결점을 지나기 때문이다.이렇게 선택하기 전 i-3-1i-1i-3 1개의 결점은 jj j 색상을 사용했다.전 i-3-1i-1i-3 1개의 결점 방안 수는 dp[i-31][j]dp[i-1][j]dp[i-31][j][j]각 방안은 dp[i][j]dp[i][j]dp[j]dp[i][j]만 대응한다

  • 4
  • 사용하지 않은 색상을 선택한다.이렇게 선택하기 전 i-3 1i-1 i-3 1개의 결점은 j-3 1j-1 j-3 1가지 색깔로 한다.전 i-3-1i-1i-3 1개의 결점 방안 수는 dp[i-3-1][j-3]dp[i-1][j-1]dp[i-3]dp[i-3][j-1]이다.각 전 i-1 방안에 대해 제j종 색깔의 선택은 k-3-j+1k-j+1k-3j+1종이 있기 때문에 각 전 i-1 방안은 k-3j+1k-j+1k-3j+1개 dp[i][j]dp[i][j]dp[i][j][j]에 대응하는 방안이다.이렇게 방정식을 옮기면 쓸 수 있다.주어진 나무 구조와는 아무런 관계가 없다는 것을 알 수 있다.

  • 코드:

    /**
    * Author : Xiuchen
    * Date : 2020-04-09-19.11.59
    * Description : dfs  +     
    */
    #pragma GCC optimize(1)
    #pragma GCC optimize(2)
    #pragma GCC optimize(3,"Ofast","inline")
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    using namespace std;
    typedef long long ll;
    const int inf = 0x3f3f3f3f;
    const ll INF = 0x3f3f3f3f3f3f3f3fLL;
    const ll mod = 1e9 + 7;
    const int maxn = 310;
    int gcd(int a, int b){
        return b ? gcd(b, a % b) : a;
    }
    int n, k;
    ll dp[maxn][maxn];
    vector<int> G[maxn];
    int main(){
        scanf("%d%d", &n, &k);
        int x, y;
        for(int i = 1; i <= n - 1; i++){
            scanf("%d%d", &x, &y);
            G[x].push_back(y);
            G[y].push_back(x);
        }
        dp[0][0] = 1;
        for(int i = 1; i <= n; i++){
            for(int j = 1; j <= k; j++)
                dp[i][j] = (dp[i - 1][j] + dp[i - 1][j - 1] * (k - j + 1) % mod) % mod;
        }
        ll ans = 0;
        for(int i = 1; i <= k; i++) ans = (ans + dp[n][i]) % mod;
        printf("%lld
    "
    , ans); return 0; }

    좋은 웹페이지 즐겨찾기