백준 18427 c++ : DP, 배낭문제

magicdrill·2024년 12월 27일

백준 문제풀이

목록 보기
517/673
post-thumbnail

백준 18427 c++ : DP, 배낭문제

입력과정에서 입력횟수가 주어지지 않고 sstream으로 한 줄마다 파싱해서 벡터에 집어넣어야 했다.
DP 수행 과정도 다른 배낭문제와 차이가 있다.

#include <iostream>
#include <vector>
#include <sstream>
#include <algorithm>

using namespace std;

void input_data(int* N, int* M, int* H, vector<vector<int>>& block) {
	cout << "\ninput_data()\n";
	int i, height;
	string line;

	cin >> *N >> *M >> *H;
	cin.ignore();
	for (i = 0; i < *N; i++) {
		getline(cin, line);
		stringstream ss(line);

		vector<int> temp_block;

		while (ss >> height) {
			temp_block.push_back(height);
		}
		//temp_block.push_back(0); //하나도 선택 안하는 경우
		//sort(temp_block.begin(), temp_block.end()); //정렬해서 순회 횟수 감소를 하는 효율이 없음
		block.push_back(temp_block);
	}

	cout << "입력 잘 됐나 확인\n";
	for (i = 0; i < block.size(); i++) {
		for (int j = 0; j < block[i].size(); j++) {
			cout << block[i][j] << " ";
		}
		cout << "\n";
	}

	return;
}

int find_answer(int N, int M, int H, vector<vector<int>>& block) {
	cout << "\nfind_answer()\n";
	int answer = 0;
	vector<int> DP(H + 1, 0);
	int i, j, k, selected_block_height, current_block_height;

	//한 학생당 최대 1개의 블록만 사용 가능. 안써도 됨
	//높이가 정확히 H인 탑을 만들 수 있는 경우의 수?

	DP[0] = 1; //어떤 블록도 선택하지 않는 경우
	for (i = 0; i < block.size(); i++) {
		vector<int> temp_DP(H + 1, 0);//기존 DP와 독립된 임시 벡터

		for (current_block_height = 0; current_block_height <= H; current_block_height++) 
		{
			if (DP[current_block_height] > 0) 
			{
				temp_DP[current_block_height] += DP[current_block_height];

				for (k = 0; k < block[i].size(); k++) 
				{
					selected_block_height = block[i][k];
					if (current_block_height + selected_block_height <= H) 
					{
						temp_DP[current_block_height + selected_block_height] += DP[current_block_height];
						temp_DP[current_block_height + selected_block_height] %= 10007;
					}
				}
			}
		}
		DP = temp_DP;

		cout << i << "번째 학생의 블록 순회 결과 : ";
		for (int temp : temp_DP) {
			cout << temp << " ";
		}
		cout << "\n";
	}
	answer = DP[H] % 10007;

	return answer;
}

int main(void) {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	int N, M, H;
	vector<vector<int>> block;

	input_data(&N, &M, &H, block);
	cout << find_answer(N, M, H, block) << "\n";

	return 0;
}

0개의 댓글