본문 바로가기

알고리즘/SWEA

2115

static int N, M, C;
static int board[10][10];
static int table[10];

static bool used[10][10];
static int alice[5];
static int bob[5];

//해당 라인에서 얻을 수 있는 최대 이윤을 구함.
static void get_tot(int y, int x, int last, int v, int tot)
{
	if (x >= last)
		return;

	for (int st = x; st < last; st++)
	{
		int nv = v + board[y][st];
		int ntot = tot + (board[y][st] * board[y][st]);

		if (nv <= C)
		{
			if (ntot > table[y])
				table[y] = ntot;

			get_tot(y, st + 1, last, nv, ntot);
		}
	}
}

//벌꿀통이 선택되었을 때 얻을 수 있는 최대 이윤을 구함.
static void get_max(int * who, int s, int v, int t, int &max)
{
	if (s >= M)
		return;

	for (int x = s; x < M; x++)
	{
		int nv = v + who[x];
		int nt = t + (who[x] * who[x]);

		if (nv <= C)
		{
			if (nt > max)
				max = nt;
			get_max(who, x + 1, nv, nt, max); //x+1 대신에 s + 1로 넘기고 있었다.
		}
	}
}

static int sel_bob(int y)
{
	int ret = 0;

	//앨리스가 선택한 것과 겹치지 않으면서 연속적으로 꿀벌통을 선택
	for (int x = 0; x < N; x++)
	{
		int cnt = 0;
		
		for (int cx = x; cx < N && cnt < M; cnt++, cx++)
		{
			if (used[y][cx])
				break;

			bob[cnt] = board[y][cx];
		}
		
		if (cnt < M)
			continue;

		int max = 0;
		get_max(bob, 0, 0, 0, max);
		if (max > ret)
			ret = max;
	}

	for (int cy = y + 1; cy < N; cy++)
	{
		if (table[cy] > ret)
			ret = table[cy];
	}

	return ret;
}

static int solution(void)
{
	int max = 0;

	scanf("%d %d %d", &N, &M, &C);
	for (int y = 0; y < N; y++)
	{
		for (int x = 0; x < N; x++)
			scanf("%d", &board[y][x]);
	}

	for (int y = 0; y < N; y++)
	{
		for (int x = 0; x + M <= N; x++)
		{
			get_tot(y, x, x + M, 0, 0); //table 초기화,
		}
	}
	
	for (int y = 0; y < N - 1; y++)
	{
		for (int x = 0; x + M <= N; x++) //필요한 개수만큼 있을 때 진행 할 수 있음,
		{
			memset(used[y], false, sizeof(used[y]));
			for (int cx = x, cnt = 0; cnt < M; cnt++, cx++)
			{
				used[y][cx] = true;
				alice[cnt] = board[y][cx];
			}

			int a = 0;
			get_max(alice, 0, 0, 0, a); //앨리스가 얻을 수 있는 최대 이윤

			a += sel_bob(y); //그 때 밥이 얻을 수 있는 최대 이윤을 추가,
			if (a > max)
				max = a;

		}
	}

	memset(table, 0, sizeof(table));
	return max;
}

코드를 더 개선할 여지가 있다. get_tot()과 get_max()를 보면 코드가 많이 유사함,

그러나 문제를 내멋대로 이해해서 어제 하루종일 삽질했고, 

채취할 꿀벌통 M개를 선택했을 때, 거기서 얻을 수 있는 최대 이윤을 구하는 방식에 결함이 있음을 너무 늦게 파악해서

더 보기가 싫다.

앞으로 모의 문제 풀이에서는 최대, 최소등을 구하거나 기타 등등, 가급적 완전 탐색을 해보는 방식으로 그 결과를 찾는 방식으로 해봐야 겠다. 

또 그 와중에, 재귀 호출 시 증가시켜 전달 할 인자를 잘못넘겨 또 뻘짓하고, ㅅㅂ

'알고리즘 > SWEA' 카테고리의 다른 글

2105  (0) 2021.11.04
4014  (0) 2021.11.04
7508  (0) 2021.11.04
8424  (0) 2021.11.04
5656  (0) 2021.11.04