https://school.programmers.co.kr/learn/courses/30/lessons/150368
행사 목적을 최대한으로 달성했을 때의 이모티콘 플러스 서비스 가입 수와 이모티콘 매출액
완전 탐색
문제를 읽으며 빠진 내용을 찾아보자.
문제의 목표가 제시되어 있다.
이모티콘 플러스 서비스 가입자를 최대한 늘리는 것.
이모티콘 판매액을 최대한 늘리는 것.
1번 목표가 우선이며, 2번 목표가 그 다음입니다.
또한 이모티콘마다 할인율이 다를 수 있으며 할인율은 10%, 20%, 30%, 40% 중 하나
로 설정된다.
그럼 전체 이모티콘의 수가 최대 7개, 정할 수 있는 할인율이 4개중 1개 이므로
7^4으로 모든 경우의 수가 정해진다.
중복을 포함한 순열을 통해서 완전 탐색이 가능하다.
중복을 통한 순열을 생성한뒤 문제에서 제시한 기준에 따라 전체 사용자를 순회하며
경우를 따져가면 된다.
class Solution {
int N;
int[] arr, price;
int[][] userInfo;
int maxUser, maxPrice;
public int[] solution(int[][] users, int[] emoticons) {
// 편리하게 전역 스코프로 복사해두자.
N = emoticons.length;
userInfo = users;
price = emoticons;
arr = new int[N];
// 최대값 초기화
maxUser = 0;
maxPrice = 0;
// 완탐
perm(0,0);
return new int[]{maxUser, maxPrice};
}
public void perm(int idx, int depth){
if(depth == N){
int count = 0;
int cost = 0;
// 모든 유저를 순회하며, 최종 금액을 계산해보고
// 개별 구매 유저인지, 플러스 구매유저인지 구분하자.
for(int[] person : userInfo){
int sum = 0;
for(int i = 0; i < N; ++i){
if(arr[i] >= person[0]){
sum += (int)(price[i] * (100-arr[i]) * 0.01);
}
}
if(sum >= person[1]){
count++;
}else{
cost += sum;
}
}
// 1번 목표가 우선이며, 2번 목표가 그 다음입니다.
// 목표 1. 이모티콘 플러스 서비스 가입자를 최대한 늘리는 것.
// 목표 2. 이모티콘 판매액을 최대한 늘리는 것.
if(count >= maxUser){
if(count > maxUser){
maxUser = count;
maxPrice = cost;
}else{
if(cost> maxPrice){
maxPrice = cost;
}
}
}
return;
}
// 할인율 10, 20, 30, 40 중 하나로 순열 생성
for(int i = 10; i <=40; i += 10){
arr[idx] = i;
perm(idx + 1, depth + 1);
}
}
}