알고리즘/코드트리 문제풀이
코드트리 [자바 java] 쪼개어 배낭 채우기 구현
잔디🌿
2023. 9. 12. 16:01
코드트리 | 코딩테스트 준비를 위한 알고리즘 정석
국가대표가 만든 코딩 공부의 가이드북 코딩 왕초보부터 꿈의 직장 코테 합격까지, 국가대표가 엄선한 커리큘럼으로 준비해보세요.
www.codetree.ai
이 문제는 보석의 수와 배낭의 크기가 주어지고, 이 배낭에 담을 수 있는 보석들의 가치의 최댓값을 구하는 문제입니다.
저는 그리디알고리즘을 사용하였습니다.
보석을 쪼갤 수 있으므로, 보석별로 부피당 가치를 구하고, 이를 오름차순으로 정렬해서 최대한 가치가 높은 것으로만 가방을 채웠습니다.
처음에는 TreeMap을 이용해서 문제를 풀었습니다.
import java.util.*;
import java.io.*;
import java.math.*;
public class Main {
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());
int[][] arr = new int[n][2];
TreeMap<Double,Integer> t = new TreeMap<>();
double[] l = new double[n];
for(int i =0;i<n;i++){
st = new StringTokenizer(br.readLine());
arr[i][0] = Integer.parseInt(st.nextToken());
arr[i][1] = Integer.parseInt(st.nextToken());
t.put(((double)arr[i][1]) / ((double)arr[i][0]), i);
l[i] = (double)arr[i][1] / (double)arr[i][0];
}
Arrays.sort(l);
double p = 0;
for(int i =n-1;i>=0;i--){
int k = t.get(l[i]);
// System.out.println(l[i]);
for(int j = arr[k][0];j>=1;j--){
if(j <= m){
m -= j;
p += j * l[i];
break;
}
}
if(m == 0) break;
}
System.out.printf("%.3f",p);
}
}
하지만 위 코드에 잘못된 부분이 있었습니다.
TreeMap에는 중복을 제외한다는 특징이 있는데, 이로 인해 간과되는 보석들이 있었습니다.
앞으로 TreeMap를 사용할 때에는 중복을 제외할 수 있는지 꼭 확인해봐야겠습니다.
import java.util.*;
import java.io.*;
import java.math.*;
public class Main {
static class j implements Comparable<j>{
int w;
int p;
j(int w, int p){
this.w = w;
this.p = p;
}
@Override
public int compareTo(j n){
double x = (double)n.p/(double)n.w - (double)this.p / (double)this.w;
if(x < 0) return -1;
else if(x == 0) return 0;
else return 1;
}
}
static ArrayList<j> jj = new ArrayList<>();
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());
for(int i =0;i<n;i++){
st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
jj.add(new j(a,b));
}
Collections.sort(jj);
double pp = 0;
for(int i =0;i<n;i++){
//System.out.println(m);
int w = jj.get(i).w;
int v = jj.get(i).p;
if(m >= w){
pp+= v;
m -= w;
}
else{
for(int j = w-1;j>=0;j--){
if(m >= j){
pp += ((double)v/(double)w) * j;
m -= j;
break;
}
}
}
}
System.out.printf("%.3f",pp);
}
}