import java.util.Scanner;
public class Solution {
public static int max = 0;
public static void main(String[] args) throws Exception {
Scanner in = new Scanner(System.in);
int testcase = in.nextInt();
for (int t = 1; t <= testcase; t++) {
max = 0;
int n = in.nextInt();
int limitCalories = in.nextInt();
int ingredients[][] = new int[n][2];
for (int i = 0; i < n; i++) {
ingredients[i][0] = in.nextInt();// 맛
ingredients[i][1] = in.nextInt();// 칼로리
}
for (int i = 0; i < n; i++) {
findMaxTaste(i, ingredients[i][0], ingredients[i][1], ingredients, limitCalories);
}
System.out.println("#" + t + " " + max);
}
}
public static void findMaxTaste(int index, int taste, int calories, int ingredients[][], int limit) {
if (calories > limit || index == ingredients.length) {
return;
}
max = Math.max(max, taste);
for (int i = index + 1; i < ingredients.length; i++) {
if (calories + ingredients[i][1] <= limit) {
findMaxTaste(i, taste + ingredients[i][0], calories + ingredients[i][1], ingredients, limit);
}
}
}
}
DP[i][j] = min(DP[i][k] + DP[k+1][j]) + (A[i] ~ A[j] 까지의 합) 일 것이고 시간 복잡도는 O(N^3)이다.
import java.util.*;
import java.io.*;
public class Main {
public static void main(String[] args) throws NumberFormatException, IOException {
Scanner in = new Scanner(System.in);
int test = in.nextInt();
for (int t = 0; t < test; t++) {
int n = in.nextInt();
int page[] = new int[n + 1];
int pageSum[] = new int[n + 1];
for (int i = 1; i <= n; i++) {
page[i] = in.nextInt();
pageSum[i] = pageSum[i - 1] + page[i];
}
int dp[][] = new int[n + 1][n + 1];
for (int i = 1; i <= n; i++) {
Arrays.fill(dp[i], -1);
}
System.out.println(DP(dp, pageSum, 1, n));
}
}
public static int DP(int dp[][], int pageSum[], int i, int j) {
if (i == j) {
dp[i][j] = 0;
return dp[i][j];
}
if (dp[i][j] != -1) {
return dp[i][j];
}
for (int k = i; k < j; k++) {
int temp = DP(dp, pageSum, i, k) + DP(dp, pageSum, k + 1, j) + pageSum[j] - pageSum[i - 1];
if (dp[i][j] == -1 || dp[i][j] > temp) {
dp[i][j] = temp;
}
}
return dp[i][j];
}
}
=> 시간복잡도는 DP를 채워야 하는 갯수 N * j를 찾는 시간 N * i~ j가 팰린드롬인지 아닌지 찾을 때 O(1): O(N^2)
import java.util.*;
import java.io.*;
public class Main {
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st;
String str = br.readLine();
char[] arr = str.toCharArray();
int n = str.length();
int dp[][] = calcPalindrome(arr, n);
int ans = calcDividedPalindrome(dp, n);
bw.write(String.valueOf(ans));
bw.flush();
bw.close();
}
public static int[][] calcPalindrome(char arr[], int n) {
int dp[][] = new int[n + 1][n + 1];
// 길이가 1일 때
for (int i = 1; i <= n; i++) {
dp[i][i] = 1;
}
// 길이가 2일 때
for (int i = 1; i <= n - 1; i++) {
if (arr[i - 1] == arr[i]) {
dp[i][i + 1] = 1;
}
}
// 길이가 3 이상
for (int i = 3; i <= n; i++) {
for (int j = 1; j <= n - i + 1; j++) {
int k = j + i - 1;
if (arr[j - 1] == arr[k - 1] && dp[j + 1][k - 1] == 1) {
dp[j][k] = 1;
}
}
}
return dp;
}
public static int calcDividedPalindrome(int dp[][], int n) {
int maxDivided[] = new int[n + 1];
for (int i = 1; i <= n; i++) {
maxDivided[i] = -1;
for (int j = 1; j <= i; j++) {
if (dp[j][i] == 1) {
if (maxDivided[i] == -1 || maxDivided[i] > maxDivided[j - 1] + 1) {
maxDivided[i] = maxDivided[j - 1] + 1;
}
}
}
}
return maxDivided[n];
}
}
BufferedWriter is a method that flush the buffer and write the characters directly to the underlying stream.
따라서 int형의 ans를 바로 bw.write하게 되면 char형으로 output이 나온다.
public class Main {
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st;
int n = Integer.parseInt(br.readLine());
int arr[] = new int[n + 1];
st = new StringTokenizer(br.readLine());
for (int i = 1; i <= n; i++) {
arr[i] = Integer.parseInt(st.nextToken());
}
int dp[][] = new int[n + 1][n + 1];
dp = calcPalindrome(arr, n);
int m = Integer.parseInt(br.readLine());
for (int i = 0; i < m; i++) {
st = new StringTokenizer(br.readLine());
int start = Integer.parseInt(st.nextToken());
int end = Integer.parseInt(st.nextToken());
bw.write(dp[start][end] + "\n");
}
bw.flush();
bw.close();
}
public static int[][] calcPalindrome(int arr[], int n) {
int dp[][] = new int[n + 1][n + 1];
// 길이가 1일 때
for (int i = 1; i <= n; i++) {
dp[i][i] = 1;
}
// 길이가 2일 때
for (int i = 1; i <= n - 1; i++) {
if (arr[i] == arr[i + 1]) {
dp[i][i + 1] = 1;
}
}
// 길이가 3 이상
for (int i = 3; i <= n; i++) {
for (int j = 1; j <= n - i + 1; j++) {
int k = j + i - 1;
if (arr[j] == arr[k] && dp[j + 1][k - 1] == 1) {
dp[j][k] = 1;
}
}
}
return dp;
}
}