[백준] 1,2,3 더하기 15988번 (java) Dynamic_programming

2020-05-12

1,2,3 더하기 3 15988번 (백준 > Dynamic_programming)

문제 링크

문제설명

정수 4를 1, 2, 3의 합으로 나타내는 방법은 총 7가지가 있다. 합을 나타낼 때는 수를 1개 이상 사용해야 한다.

  • 1+1+1+1
  • 1+1+2
  • 1+2+1
  • 2+1+1
  • 2+2
  • 1+3
  • 3+1

정수 n이 주어졌을 때, n을 1, 2, 3의 합으로 나타내는 방법의 수를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 테스트 케이스의 개수 T가 주어진다. 각 테스트 케이스는 한 줄로 이루어져 있고, 정수 n이 주어진다. n은 양수이며 1,000,000보다 작거나 같다.

출력

각 테스트 케이스마다, n을 1, 2, 3의 합으로 나타내는 방법의 수를 1,000,000,009로 나눈 나머지를 출력한다.

예제 입력 1 복사

3
4
7
10

예제 출력 1 복사

7
44
274

풀이

package Dynamic_programming;

//20min
import java.util.*;

public class beak_123더하기3 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		
		long dp[] = new long[1000001];
		
		dp[0] = 0;
		dp[1] = 1;
		dp[2] = 2;
		dp[3] = 4;
		
		for(int i=4; i<=1000000; i++) {
			dp[i] = (dp[i-1] + dp[i-2] + dp[i-3])%1000000009;
		}
		
		int n = sc.nextInt();
		for(int i=0; i<n; i++) {
			int k = sc.nextInt();
			System.out.println(dp[k]);
		}
	}
}

후기 (20min)

숫자가 커서 나누기를 답으로 하는 문제들은 대부분 long으로 바꿔준 후 풀 것!!

Read More

[백준] 1,2,3 더하기 9095번 (java) Dynamic_programming

2020-05-12

1,2,3 더하기 9095번 (백준 > Dynamic_programming)

문제 링크

문제설명

정수 4를 1, 2, 3의 합으로 나타내는 방법은 총 7가지가 있다. 합을 나타낼 때는 수를 1개 이상 사용해야 한다.

  • 1+1+1+1
  • 1+1+2
  • 1+2+1
  • 2+1+1
  • 2+2
  • 1+3
  • 3+1

정수 n이 주어졌을 때, n을 1, 2, 3의 합으로 나타내는 방법의 수를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 테스트 케이스의 개수 T가 주어진다. 각 테스트 케이스는 한 줄로 이루어져 있고, 정수 n이 주어진다. n은 양수이며 11보다 작다.

출력

각 테스트 케이스마다, n을 1, 2, 3의 합으로 나타내는 방법의 수를 출력한다.

예제 입력 1 복사

3
4
7
10

예제 출력 1 복사

7
44
274

풀이

package DP;

import java.util.*;

public class beak_123더하기_re {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		
		//정수 n을 1,2,3으로 나타내는 법
		int dp[] = new int[11];
		dp[0] = 0;
		dp[1] = 1;
		dp[2] = 2;
		dp[3] = 4;
			
		for(int j=4; j<=10; j++) {
			dp[j] = dp[j-1] + dp[j-2] + dp[j-3];
		}
		
		int n = sc.nextInt();
		
		for(int i=0; i<n; i++) {
			int num = sc.nextInt();
			System.out.println(dp[num]);
		}

	}
}

후기 (15min)

조건을 잘 보자! 10이하니까 dp[10]까지만 만들어놓으면 된다!

Read More

[프로그래머스] 퇴사 (java) Dynamic_programming

2020-05-05

퇴사 (백준 > Dynamic_programming)

문제 링크

문제설명

상담원으로 일하고 있는 백준이는 퇴사를 하려고 한다.

오늘부터 N+1일째 되는 날 퇴사를 하기 위해서, 남은 N일 동안 최대한 많은 상담을 하려고 한다.

백준이는 비서에게 최대한 많은 상담을 잡으라고 부탁을 했고, 비서는 하루에 하나씩 서로 다른 사람의 상담을 잡아놓았다.

각각의 상담은 상담을 완료하는데 걸리는 기간 Ti와 상담을 했을 때 받을 수 있는 금액 Pi로 이루어져 있다.

N = 7인 경우에 다음과 같은 상담 일정표를 보자.

  1일 2일 3일 4일 5일 6일 7일
Ti 3 5 1 1 2 4 2
Pi 10 20 10 20 15 40 200

1일에 잡혀있는 상담은 총 3일이 걸리며, 상담했을 때 받을 수 있는 금액은 10이다. 5일에 잡혀있는 상담은 총 2일이 걸리며, 받을 수 있는 금액은 15이다.

상담을 하는데 필요한 기간은 1일보다 클 수 있기 때문에, 모든 상담을 할 수는 없다. 예를 들어서 1일에 상담을 하게 되면, 2일, 3일에 있는 상담은 할 수 없게 된다. 2일에 있는 상담을 하게 되면, 3, 4, 5, 6일에 잡혀있는 상담은 할 수 없다.

또한, N+1일째에는 회사에 없기 때문에, 6, 7일에 있는 상담을 할 수 없다.

퇴사 전에 할 수 있는 상담의 최대 이익은 1일, 4일, 5일에 있는 상담을 하는 것이며, 이때의 이익은 10+20+15=45이다.

상담을 적절히 했을 때, 백준이가 얻을 수 있는 최대 수익을 구하는 프로그램을 작성하시오.

입력

첫째 줄에 N (1 ≤ N ≤ 15)이 주어진다.

둘째 줄부터 N개의 줄에 Ti와 Pi가 공백으로 구분되어서 주어지며, 1일부터 N일까지 순서대로 주어진다. (1 ≤ Ti ≤ 5, 1 ≤ Pi ≤ 1,000)

출력

첫째 줄에 백준이가 얻을 수 있는 최대 이익을 출력한다.

예제 입력 1 복사

7
3 10
5 20
1 10
1 20
2 15
4 40
2 200

예제 출력 1 복사

45

풀이

package DP;

import java.util.*;
public class beak_re_퇴사 {
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		
		int n = sc.nextInt();
		
		int t[] = new int[n+2];
		int p[] = new int[n+2];
		
		for(int i=1; i<=n;i++) {
			t[i] = sc.nextInt();
			p[i] = sc.nextInt();
		}
	
		int dp[] = new int[n+2];
		for(int i=n; i>=1; i--) {//끝에서부터
			int day = i +t[i]; //일 끝나는 시간
			
			if(day <=n+1) // 끝나는 시간이 n안쪽이면 (k라면) k 날의 값도 가질 수 있다
				dp[i] = Math.max(p[i] + dp[day], dp[i+1]);
			else // 시간안에 못끝나는 일이면
				dp[i] = dp[i+1]; // 자기자신은 값을 못가지니까 다음날의 값, 만약 다음날도 값이 없다면? 계속 0이겠지
		}
		
		System.out.println(dp[1]);
		
	}
}

후기 (1h)

으아… 다 해놓고 if(day <=n+1) 여기서 시간 다날림….아….퇴사씨….

Read More

[프로그래머스] 섬의 개수 (java) Dfs

2020-05-05

섬의 개수 (백준 > Dfs_Bfs)

문제 링크

문제설명

정사각형으로 이루어져 있는 섬과 바다 지도가 주어진다. 섬의 개수를 세는 프로그램을 작성하시오.

img

한 정사각형과 가로, 세로 또는 대각선으로 연결되어 있는 사각형은 걸어갈 수 있는 사각형이다.

두 정사각형이 같은 섬에 있으려면, 한 정사각형에서 다른 정사각형으로 걸어서 갈 수 있는 경로가 있어야 한다. 지도는 바다로 둘러싸여 있으며, 지도 밖으로 나갈 수 없다.

입력

입력은 여러 개의 테스트 케이스로 이루어져 있다. 각 테스트 케이스의 첫째 줄에는 지도의 너비 w와 높이 h가 주어진다. w와 h는 50보다 작거나 같은 양의 정수이다.

둘째 줄부터 h개 줄에는 지도가 주어진다. 1은 땅, 0은 바다이다.

입력의 마지막 줄에는 0이 두 개 주어진다.

출력

각 테스트 케이스에 대해서, 섬의 개수를 출력한다.

예제 입력 1 복사

1 1
0
2 2
0 1
1 0
3 2
1 1 1
1 1 1
5 4
1 0 1 0 0
1 0 0 0 0
1 0 1 0 1
1 0 0 1 0
5 4
1 1 1 0 1
1 0 1 0 1
1 0 1 0 1
1 0 1 1 1
5 5
1 0 1 0 1
0 0 0 0 0
1 0 1 0 1
0 0 0 0 0
1 0 1 0 1
0 0

예제 출력 1 복사

0
1
1
3
1
9

풀이

package Dfs_Bfs;

import java.util.*;

public class beak_섬의개수 {
	
	public static void dfs(int arr[][], int x, int y) {
		arr[x][y] = 0;
		
		int dx[] = {-1,-1,-1, 0, 0, 1, 1, 1};
		int dy[] = {-1, 0, 1,-1, 1,-1, 0, 1};
		
		for(int i=0; i<8; i++) {
			int nx = x + dx[i];
			int ny = y + dy[i];
			
			if(nx>=0 && nx<arr.length && ny>=0 && ny<arr[0].length
					&& arr[nx][ny] !=0)
				dfs(arr, nx,ny);
		}
	}
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		
		while(true) {
			int m = sc.nextInt();
			int n = sc.nextInt();
			
			if(n == 0 && m==0)
				break;
			
			if(n ==1 && m==1) {
				int k = sc.nextInt();
				if(k == 0)
					System.out.println(0);
				else
					System.out.println(1);
				
				continue;
			}
			
			int arr[][] = new int[n][m];
			
			for(int i=0; i<n; i++) {
				for(int j=0; j<m; j++)
					arr[i][j] = sc.nextInt();
			}
			
			int answer = 0;
			for(int i=0; i<n; i++) {
				for(int j=0; j<m; j++){
					if(arr[i][j] !=0) {
						dfs(arr,i,j);
						answer++;
					}
				}
			}//dfs
			
			System.out.println(answer);
		}
	}
}

후기 (15min)

오랜만에 풀어본 섬의 개수 문제!

Read More

[프로그래머스] 다트게임 (java) Stack_Queue

2020-05-05

다트게임 (프로그래머스 > Stack_Queue)

문제 링크

문제설명

카카오톡 게임별의 하반기 신규 서비스로 다트 게임을 출시하기로 했다. 다트 게임은 다트판에 다트를 세 차례 던져 그 점수의 합계로 실력을 겨루는 게임으로, 모두가 간단히 즐길 수 있다. 갓 입사한 무지는 코딩 실력을 인정받아 게임의 핵심 부분인 점수 계산 로직을 맡게 되었다. 다트 게임의 점수 계산 로직은 아래와 같다.

  1. 다트 게임은 총 3번의 기회로 구성된다.
  2. 각 기회마다 얻을 수 있는 점수는 0점에서 10점까지이다.
  3. 점수와 함께 Single(S), Double(D), Triple(T) 영역이 존재하고 각 영역 당첨 시 점수에서 1제곱, 2제곱, 3제곱 (점수1 , 점수2 , 점수3 )으로 계산된다.
  4. 옵션으로 스타상(*) , 아차상(#)이 존재하며 스타상(*) 당첨 시 해당 점수와 바로 전에 얻은 점수를 각 2배로 만든다. 아차상(#) 당첨 시 해당 점수는 마이너스된다.
  5. 스타상(*)은 첫 번째 기회에서도 나올 수 있다. 이 경우 첫 번째 스타상(*)의 점수만 2배가 된다. (예제 4번 참고)
  6. 스타상(*)의 효과는 다른 스타상(*)의 효과와 중첩될 수 있다. 이 경우 중첩된 스타상(*) 점수는 4배가 된다. (예제 4번 참고)
  7. 스타상(*)의 효과는 아차상(#)의 효과와 중첩될 수 있다. 이 경우 중첩된 아차상(#)의 점수는 -2배가 된다. (예제 5번 참고)
  8. Single(S), Double(D), Triple(T)은 점수마다 하나씩 존재한다.
  9. 스타상(*), 아차상(#)은 점수마다 둘 중 하나만 존재할 수 있으며, 존재하지 않을 수도 있다.

0~10의 정수와 문자 S, D, T, *, #로 구성된 문자열이 입력될 시 총점수를 반환하는 함수를 작성하라.

입력 형식

점수|보너스|[옵션]으로 이루어진 문자열 3세트. 예) 1S2D*3T

  • 점수는 0에서 10 사이의 정수이다.
  • 보너스는 S, D, T 중 하나이다.
  • 옵선은 *이나 # 중 하나이며, 없을 수도 있다.

출력 형식

3번의 기회에서 얻은 점수 합계에 해당하는 정수값을 출력한다. 예) 37

입출력 예제

예제 dartResult answer 설명
1 1S2D*3T 37 11 * 2 + 22 * 2 + 33
2 1D2S#10S 9 12 + 21 * (-1) + 101
3 1D2S0T 3 12 + 21 + 03
4 1S*2T*3S 23 11 * 2 * 2 + 23 * 2 + 31
5 1D#2S*3S 5 12 * (-1) * 2 + 21 * 2 + 31
6 1T2D3D# -4 13 + 22 + 32 * (-1)
7 1D2S3T* 59 12 + 21 * 2 + 33 * 2

풀이

import java.util.*;

class Solution {
  public int solution(String dartResult) {
      int answer = 0;
      LinkedList<Integer> list = new LinkedList<>();
      
      //무조건 숫자 + STD + * 
      for(int i=0; i<dartResult.length(); i++){
          char c = dartResult.charAt(i);
          
          if(c =='0' || c =='1' ||c =='2' ||c =='3' ||c =='4' ||c =='5' ||c =='6' ||c =='7' ||c =='8' ||c =='9'){
              if(i+1 <dartResult.length() && dartResult.charAt(i+1) =='0'){
                  list.add(10);               
                  i++;
              }
              else
                  list.add(Integer.parseInt(String.valueOf(c)));
          }
          
          else if(c == 'T'|| c == 'D' || c=='S'){
              if(c == 'D'){
                  int n = list.removeLast();
                  list.add(n*n);
              }
              else if(c == 'T'){
                  int n = list.removeLast();
                  list.add(n*n*n);
              }   
          }
          
          else{
              if(c == '*'){
                  if(list.size()==1){
                      int n = list.removeLast();
                      list.add(n*2);
                  }
                  else if(list.size()>=2){
                      int n1 = list.removeLast();
                      int n2 = list.removeLast();
                      
                      list.add(n2*2);
                      list.add(n1*2);
                  }
              }
              
              if(c == '#'){
                  int n = list.removeLast();
                  list.add(n*-1);
              }
          }    
      }
      
      for(int i=0; i<list.size(); i++)
          answer += list.get(i);
      
      return answer;
  }
}

후기 (40min)

이게 사십분이나 걸릴 문제 인가요…!

굳이 while 쓰면서 숫자 찾는데 복잡하게 시간 쓸 생각 하지 말고 **차라리   많이 써가면서 더러워 보이더라도 빠르게 풀도록 노력하자**!!! 제발!
Read More