현재 상황에서 가장 좋은 것만 고르를 것 (탐욕법)
=> 현상황에서 가장 좋은 것만 고를 때 최적해를 구할 수있는 문제인지 확인해야함
(코테에서 그리디 문제는 그리디로 얻은해가 최적해가 되는 상황에서 이를 추론 할 수 있어야 풀리도록 출제됨)
n개의 로프를 모두 사용한다면 가장 작은 로프가 들 수 있는 무게n이 가장 가장 많이 들 수 있는 무게이다.
로프를 오름차순으로 정렬한 후 가장 작은 로프n의 최대값을 구하면 된다.
import java.util.*;
public class 백준2217 {
static int n,m,cnt=0,answer=0;
static Scanner scan =new Scanner(System.in);
static int MAX=Integer.MIN_VALUE;
static StringBuilder sb=new StringBuilder();
static String[] str;
static int[] arr;
public static void main(String[] args) {
//출력 : 들어올릴수있는 물체의 최대 중량
//가장 작은 로프의 *n한 값
n=scan.nextInt();
arr=new int[n];
for(int i=0;i<n;i++) {
arr[i]=scan.nextInt();
}
Arrays.sort(arr);
int a=n;
for(int i=0;i<n;i++) {
MAX=Math.max(arr[i]*a, MAX);
a--;
}
System.out.print(MAX);
}
}
가장 주의해야할 것은 범위에 따른 자료형이고
풀이방법을 최적화 안하면 100점을 주지않는다!
import java.util.*;
public class 백준13305 {
static int n,m,cnt=0,answer=0;
static long ans=0;
static Scanner scan =new Scanner(System.in);
static long MIN=Long.MAX_VALUE;
static StringBuilder sb=new StringBuilder();
static long[] arr;
static long[] arr2;
public static void main(String[] args) {
//출력 : 최소 비용
n=scan.nextInt(); //도시의 갯수
arr=new long[n];
arr2=new long[n];
for(int i=0;i<n-1;i++) {//도로의 길이 n-1개
arr[i]=scan.nextLong();
}
for(int j=0;j<n;j++) { //주유소의 리터당 가격
arr2[j]=scan.nextLong();
}
for(int i=0;i<n;i++) {
if (arr2[i]<MIN) {
MIN=arr2[i];
}
ans+=MIN*arr[i];
}
System.out.print(ans);
}
}
`
import java.util.*;
public class Main {
static int n,m,cnt=0,answer=0;
static Scanner scan =new Scanner(System.in);
static long MIN=Long.MAX_VALUE, leng;
static StringBuilder sb=new StringBuilder();
static String[] str;
static long[] arr;
static long[] arr2;
public static void main(String[] args) {
//출력 : 최소 비용
n=scan.nextInt(); //도시의 갯수
arr=new long[n];
arr2=new long[n];
for(int i=0;i<n-1;i++) {//도로의 길이 n-1개
arr[i]=scan.nextLong();
leng+=arr[i]; //도로 총길이
}
for(int j=0;j<n-1;j++) { //주유소의 리터당 가격
arr2[j]=scan.nextLong();
}
long nxt=0;
for(int i=0;i<n-1;i++) {
MIN=Math.min(MIN,nxt+arr2[i]*leng);
nxt+=arr[i]*arr2[i];
leng-=arr[i];
}
System.out.print(MIN);
}
}
import java.util.*;
public class Main {
static int n,m,cnt=0,answer=0;
static long ans=0;
static Scanner scan =new Scanner(System.in);
static HashMap<Integer,Integer> map=new HashMap<>();
static double MIN=Double.MAX_VALUE;
static StringBuilder sb=new StringBuilder();
static String[] str;
static long[] arr;
static long[] arr2;
public static void main(String[] args) {
//출력 : 최소 비용
n=scan.nextInt(); //도시의 갯수
arr=new long[n];
arr2=new long[n];
for(int i=0;i<n-1;i++) {//도로의 길이 n-1개
arr[i]=scan.nextLong();
}
for(int j=0;j<n;j++) { //주유소의 리터당 가격
arr2[j]=scan.nextLong();
}
for(int i=0;i<n;i++) {
if (arr2[i]<MIN) {
MIN=arr2[i];
}
ans+=MIN*arr[i];
}
System.out.print(ans);
}
}
그냥 내림차순 정렬해주고 값구하면 되는 문제 ~ 완전 쉽다 라고 생각했는데
생각외로 시간을 많이 잡아먹었다
참고로 자료형도 주의해야한다. 범위가 int를 넘을 것같다.
import java.util.*;
public class 백준1758 {
static int n,m,cnt=0,answer=0;
static long ans=0;
static Scanner scan =new Scanner(System.in);
static long MIN=Long.MAX_VALUE;
static StringBuilder sb=new StringBuilder();
static Integer[] arr;
public static void main(String[] args) {
// TODO Auto-generated method stub
n=scan.nextInt(); //사람의 수
arr=new Integer[n];
for(int i=0;i<n;i++) {
arr[i]=scan.nextInt();
}
Arrays.sort(arr,Comparator.reverseOrder());
for(int i=0;i<n;i++) {
long tip= arr[i]-(i);
if(tip<0) {
tip=0;
}
ans+=tip;
}
System.out.print(ans);
}
}
풀이방법은 윗문제와 같다
import java.util.*;
public class 백준11508 {
static int n,m,cnt=0,answer=0;
static long ans=0;
static Scanner scan =new Scanner(System.in);
static long MIN=Long.MAX_VALUE;
static StringBuilder sb=new StringBuilder();
static Integer[] arr;
public static void main(String[] args) {
// TODO Auto-generated method stub
n=scan.nextInt();
arr=new Integer[n];
for(int i=0;i<n;i++) {
arr[i]=scan.nextInt();
}
Arrays.sort(arr,Comparator.reverseOrder());
for(int i=0;i<n;) {
if(n-i<3) {
ans+=arr[i];
i++;
}
else {
ans+=arr[i]+arr[i+1];
i+=3;
}
}
System.out.print(ans);
}
}
풀이는 위와 같다 문제가 다 비슷비슷 하구나~
import java.util.*;
public class 백준11399 {
static int n,m,cnt=0,answer=0;
static long ans=0;
static Scanner scan =new Scanner(System.in);
static long MIN=Long.MAX_VALUE;
static StringBuilder sb=new StringBuilder();
static Integer[] arr;
public static void main(String[] args) {
// TODO Auto-generated method stub
n=scan.nextInt();
arr=new Integer[n];
for(int i=0;i<n;i++) {
arr[i]=scan.nextInt();
}
Arrays.sort(arr);
int a=n;
for(int i=0;i<n;i++) {
ans+=arr[i]*a;
a--;
}
System.out.print(ans);
}
}
/2를 하는 과정에서 소수점이 나올수도 있기때문에 double 형을 써주었다
풀이는 위와같습니다
import java.util.*;
public class 백준20115 {
static int n,m,cnt=0,answer=0;
static double ans=0;
static Scanner scan =new Scanner(System.in);
static long MIN=Long.MAX_VALUE;
static StringBuilder sb=new StringBuilder();
static Integer[] arr;
public static void main(String[] args) {
// TODO Auto-generated method stub
n=scan.nextInt();
arr=new Integer[n];
for(int i=0;i<n;i++) {
arr[i]=scan.nextInt();
}
Arrays.sort(arr);
for(int i=0;i<n;i++) {
if(i==n-1) {
ans+=arr[i];
}
else ans+=(double)arr[i]/2;
}
System.out.print(ans);
}
}
import java.util.*;
public class 백준1541 {
static int i,n,m,cnt=0,answer=0;
static int ans=0;
static Scanner scan =new Scanner(System.in);
static long MIN=Long.MAX_VALUE;
static StringBuilder sb=new StringBuilder();
static int[] arr;
public static void main(String[] args) {
// TODO Auto-generated method stub
String str=scan.next();
int leng=str.length();
for(;i<leng;) {
if(i==0) {
ans+=cal(str);
}
else {
if(str.charAt(i)=='-') {
i++;
while(i<leng) {
if(str.charAt(i)=='-') {
i++;
break;
}
ans-=cal(str);
i++;
}
}
else {
i++;
ans+=cal(str);
}
}
}
System.out.print(ans);
}
static int cal(String str) {
String num="";
while(i<str.length()&&str.charAt(i)!='-'&&str.charAt(i)!='+') {// 부호 나올 때까지
num+=str.charAt(i);
i++;
}
return Integer.parseInt(num);
}
}
아이디어만 도출해내면 쉬운문제라고 생각하고 금방 풀었지만 47%에서 계속 시간초과가 났다. 오랫동안 47%에서 머물러있어서 무한루프에 걸린게 아닐까 생각했는데 아니나다를까 while문의 ans!=a조건이나 내부의 if문의 조건 모두 만족하지않는 반례가 있었다. 만약 ans가 3이고 a가 2라면 아무조건에도 만족하지않으므로 무한루프에 빠지게 되는것! 그래서 else문으로 예외처리를 해주었다.
import java.util.Scanner;
public class 백준16953 {
static long a,b,cnt=0,answer=0;
static long ans=0;
static Scanner scan =new Scanner(System.in);
static StringBuilder sb=new StringBuilder();
public static void main(String[] args) {
// TODO Auto-generated method stub
a=scan.nextLong();
b=scan.nextLong();
if(b%2!=0&&b%10!=1) { //2로 나누어 떨어지지 않고 1로 끝나지도 않는 수이면
System.out.print(-1);
System.exit(0);
}
else {
ans=b;
while(ans!=a) {
if(ans<a) {
System.out.print(-1);
System.exit(0);
}
if(ans%10==1&&ans!=1) { //1로 끝나는 수이면
ans=(ans-1)/10;
cnt++;
}
else if(ans%2==0) {
ans=ans/2;
cnt++;
}
else {
System.out.print(-1);
System.exit(0);
}
}
}
System.out.print(cnt+1);
}
}