白俊1010号です.


1010番
👍 質問する
재원이는 한 도시의 시장이 되었다. 이 도시에는 도시를 동쪽과 서쪽으로 나누는 큰 일직선 모양의 강이 흐르고 있다.
하지만 재원이는 다리가 없어서 시민들이 강을 건너는데 큰 불편을 겪고 있음을 알고 다리를 짓기로 결심하였다.
강 주변에서 다리를 짓기에 적합한 곳을 사이트라고 한다.
재원이는 강 주변을 면밀히 조사해 본 결과 강의 서쪽에는 N개의 사이트가 있고 동쪽에는 M개의 사이트가 있다는 것을 알았다. (N ≤ M)

재원이는 서쪽의 사이트와 동쪽의 사이트를 다리로 연결하려고 한다.
(이때 한 사이트에는 최대 한 개의 다리만 연결될 수 있다.)
재원이는 다리를 최대한 많이 지으려고 하기 때문에 서쪽의 사이트 개수만큼 (N개) 다리를 지으려고 한다.
다리끼리는 서로 겹쳐질 수 없다고 할 때 다리를 지을 수 있는 경우의 수를 구하는 프로그램을 작성하라.
👍 入力/出力
입력 : 테스트 케이스 수인 T, T만큼의 (N,M) 쌍 입력받음
출력 : 해당 (N,M) 경우에 따라 다리를 지을 수 있는 경우의 수
👍 自分で説明しますか?
まず以下のコードで「動的プログラミング」を用いた.
西側に4つのサイトがあり、右側に7つのサイトがある場合
最西方のサイトをAサイトと仮定すると、Aは右側の7つのサイト(a,b,c,d,e,f,g)に
各接続に1つあると仮定します.
右側6個(A-a)、5個(A-b)、・・・0(A-g)個に接続されている場合
(左4個、右7個)に繋げることができる偽の数字はすべて出てきます.
つまり、それを一般化すれば、
dp[N][M] = dp[N-1][M-1] + ... + dp[N-1][0]
表示できます.
N=1の場合はMの数なので入手しやすい.
Nが2より大きい場合、N−1の結果に基づいて簡単に取得することができる.
ダイナミックプログラミングで解決できます.
이 중 N이 M보다 큰 경우는
dp[N][M] = 0으로 되어있어 계산에 영향을 주지 않음.
전역변수로 고정된 값으로 배열선언만하고 value 지정 없을시 배열내의 모든 값은 0으로 초기화가 된다.
👍 c++正しいコード
#include <bits/stdc++.h>
using namespace std;

int dp[31][31];

int main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    
    for (int i = 1; i <= 30; i++)
        dp[1][i] = i;

    for (int i = 2; i <= 30; i++) {
        for (int j = i; j <= 30; j++) {
	    for (int k = j - 1; k >= 1; k--) {
			    dp[i][j] += dp[i - 1][k];
		    }
	    }
    }

    int T;
    cin >> T;
    
    while (T--) {
        int n, m;
        cin >> n >> m;
        cout << dp[n][m] << "\n";
    }
    return 0;
}