[白俊]#18427一緒に積み木
質問する
1番からN番までの学生はそれぞれいくつかのブロックがあります.各学生は最大M個のブロックを持つことができ、各学生が持つすべてのブロックの高さは異なる.このとき、1番からN番までの生徒たちは順番に自分の積み木を使い、地面から積み上げてタワーを形成します.
しかし、一部の学生のブロックは使用する必要がなく、学生ごとに最大1つのブロックしか使用できません.
1番からN番までの生徒の積み木についての情報があれば、高さHの塔を作ることができれば、数字を計算するプログラムを作成します.
例えば、N=3、M=3、H=5の場合、各生徒が持つブロックの高さは以下のように仮定される.
入力
1行目は、スペースを基準に自然数N,M,Hを分割します.(1≦N≦50,1≦M≦10,1≦H≦1000)2行目から,各学生が持つブロックの高さをスペースに準じて学生に区分する.
しかし,各ブロックの高さは1000以下の自然数であり,学生ごとに所有するすべてのブロックの高さは異なる.
しゅつりょく
最初の行にHの高さのタワーを作成すると、その数を10007で割って残りを出力します.
入力例1
3 3 5
2 3 5
3 5
1 2 3
サンプル出力1
6
に答える
この問題は動的プログラミングアルゴリズムで解決できる.
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
public class Main {
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] input = br.readLine().split(" ");
int N = Integer.parseInt(input[0]);
int H = Integer.parseInt(input[2]);
int[][] dp = new int[N+1][H+1];
ArrayList<Integer>[] list = new ArrayList[N+1];
for(int i=1; i<=N; i++)
list[i] = new ArrayList<>();
for(int i=1; i<=N; i++) {
input = br.readLine().split(" ");
for(int j=0; j<input.length; j++)
list[i].add(Integer.parseInt(input[j]));
}
for(int i=0; i<=N; i++) //0일 가능성은 모두 1이기 때문에
dp[i][0] = 1;
for(int i=1; i<=N; i++) {
for(int j=1; j<=H; j++) {
for(int x : list[i]) {
if(j>=x) {
dp[i][j] += dp[i-1][j-x] %= 10007; //해당 블록을 쌓을수 있는 경우 더해줌
}
}
dp[i][j] += dp[i-1][j] %= 10007; //블록을 안쌓을 경우
}
}
System.out.println(dp[N][H]%10007);
}
}
Reference
この問題について([白俊]#18427一緒に積み木), 我々は、より多くの情報をここで見つけました https://velog.io/@pss407/백준18427-함께-블록-쌓기テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol