증명 블로그

https://rkm0959.wordpress.com/2017/03/17/inequality-for-the-minimum-number-of-squares-to-partition-a-rectangle/

import java.util.*;
import java.io.*;
/**
* BOJ 10803 정사각형 만들기
* https://gist.github.com/KSH-code/387282e835efe598bf68faea5129c627
*/
/**
* 아이디어
* max % min == 0 => dp[max][min] = max / min
* dp[i][2] = 2로 나눠지면 i/2 else i/2 + 2
* ============================================================
* 위에 있는게 아닌 경우 solve way 를 찾아야됨
* ============================================================
* 11/6 2017 첫 번째 방법
* dp[i][j] = dp[i-j][j] + 1
* ============================================================
* 11/6 2017 두 번째 방법
* i가 홀수면 dp[i][j] = min(dp[i/2][j] + dp[i/2+1][j], i / j + j)
* i가 짝수면 dp[i][j] = min(dp[i/2][j] * 2, i / j + j)
* 위에 방법을 j에도 대입
* 약간 수정해서 1부터 y/2~x/2 하나씩 해봄
* ============================================================
*/
class Main {
private static int memoization[][] = new int[10001][101];
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
String str1[] = br.readLine().split(" ");
int N = Integer.parseInt(str1[0]);
int M = Integer.parseInt(str1[1]);
int max = max(N, M);
int min = min(N, M);
for(int i = 1; i<=max; i++){
memoization[i][1] = i;
if(i <= min){
memoization[i][i] = 1;
}
if(i >= 3){
if(i % 2 == 0){
memoization[i][2] = i / 2;
}else{
memoization[i][2] = i / 2 + 2;
}
}
}
dp(max, min);
bw.write(String.valueOf(memoization[max][min]));
bw.flush();
}
private static int dp(int x, int y){
int tempMax = max(x, y);
int tempMin = min(x, y);
x = tempMax;
y = tempMin;
if(memoization[x][y] == 0){
int min = 12341234;
if(x % y == 0){
return memoization[x][y] = min(x/y, min);
}
if(x >= y * 3){
return memoization[x][y] = dp(x-y, y) + 1;
}
for(int i=1; i<= x / 2; i++){
min = min(min, dp(x - i, y) + dp(i, y));
}
for(int i=1; i<= y / 2; i++){
min = min(min, dp(x, y-i) + dp(x, i));
}
return memoization[x][y] = min;
}else{
return memoization[x][y];
}
}
private static int max(int a, int b){
if(a > b){
return a;
}else{
return b;
}
}
private static int min(int a, int b){
if(a < b){
return a;
}else{
return b;
}
}
}
// 첫 번째 아이디어 실패.
// for(int i = 1; i<=max; i++){
// for(int j = 1; j<=min; j++){
// if(dp[i][j] == 0 && i > 2 && j != 2){
// int minTemp = max(i, j) - min(i, j);
// int maxTemp = min(i, j);
// if(i == 6 && j == 5 || minTemp < 0){
// System.out.println(i);
// System.out.println(j);
// System.out.println(maxTemp);
// System.out.println(minTemp);
// }
// dp[i][j] = dp[maxTemp][minTemp] + 1;
// }
// }
// }
view raw Main.java hosted with ❤ by GitHub


3개의 풀이가 나왔다.

1. 시간초과

하나씩 다 더해줌

2. 런타임

2차원 배열을 만들어서 무게별로 나누고 또 거기에서 컬러별로 나눴음

2000 * 2e5 * 4 = 1G가 넘어가서 런타임 에러

3. 정답

블로그를 조금 참고했지만, 짜고나니 거의 똑같게 나옴...

total 스코어 idea를 참고함.

import java.util.*;
import java.io.*;
/**
* BOJ 10800 컬러볼 풀이
* https://gist.github.com/KSH-code/e705293348cbd1aea4567002e516a388
*/
class Ball implements Comparable<Ball>{
public int color, weight, idx;
public Ball(int color, int weight, int idx){
this.color = color;
this.weight = weight;
this.idx = idx;
}
@Override
public int compareTo(Ball arg){
return this.weight - arg.weight;
}
}
class Main {
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
int N = Integer.parseInt(br.readLine());
int score[] = new int[N];
int color[] = new int[N+1];
int total = 0;
Ball temp[] = new Ball[N];
for(int i = 0; i<N; i++){
String str1[] = br.readLine().split(" ");
int c = Integer.parseInt(str1[0]);
int w = Integer.parseInt(str1[1]);
temp[i] = new Ball(c, w, i);
}
Arrays.sort(temp);
for(int i = 0, j = 0; i<N; i++){
for(; temp[j].weight<temp[i].weight; j++){
total += temp[j].weight;
color[temp[j].color] += temp[j].weight;
}
score[temp[i].idx] += total - color[temp[i].color];
}
for(int i = 0; i<N; i++){
bw.write(score[i] + "\n");
}
bw.flush();
}
}
view raw Main.java hosted with ❤ by GitHub


스터디에서 순열과 조합을 공부한다.(순열은 아직 뭔지 모름)

조합 문제를 풀었다.


분자식이 나오는데, 분자식이 어떤건지 몰라서 도움을 많이 받았다.

문제는 M1 + M2 = M3 가 균형이 맞으면 된다.

원자번호로 균형을 맞추는게 아니라 각 원자의 갯수를 맞춰야 된다.


아이디어만 있으면 쉽게 풀 수 있는 문제.


import java.io.*;
import java.util.*;
/**
* BOJ 1907 탄소 화합물
* https://gist.github.com/KSH-code/a53903cfa3d3ed0a0391637676d058a5
*/
class Main{
private static int q[][] = new int[3][3];
private static int result[] = new int[3];
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String s = br.readLine();
String M123[] = s.split("\\+");
String M1 = M123[0];
String M23[] = M123[1].split("=");
String M2 = M23[0];
String M3 = M23[1];
Arrays.fill(result, 1);
divide(M1, 0, 0);
divide(M2, 0, 1);
divide(M3, 0, 2);
for(int i = 1; i<=10; i++){
for(int k = 1; k<= 10; k++){
for(int j = 1; j<= 10; j++){
int C,H,O;
C = j * q[1][0] + k * q[0][0];
H = j * q[1][1] + k * q[0][1];
O = j * q[1][2] + k * q[0][2];
int CC,HH,OO;
CC = i * q[2][0];
HH = i * q[2][1];
OO = i * q[2][2];
if(C == CC){
if(H == HH){
if(O == OO){
System.out.println(k + " " + j + " " + i);
return;
}
}
}
}
}
}
}
private static void divide(String s, int idx, int midx){
if(idx >= s.length())
return;
switch (s.charAt(idx)) {
case 'C':
q[midx][0] += getCount(s, idx+1);
break;
case 'H':
q[midx][1] += getCount(s, idx+1);
break;
case 'O':
q[midx][2] += getCount(s, idx+1);
break;
default:
break;
}
divide(s, idx + 1, midx);
}
private static int getCount(String s, int idx){
if(idx >= s.length()){
return 1;
}else{
if(s.charAt(idx) >= '2' && s.charAt(idx) <= '9'){
return s.charAt(idx) - 48;
}else{
return 1;
}
}
}
}
view raw Main.java hosted with ❤ by GitHub


+ Recent posts