https://www.acmicpc.net/problem/1208
1208번: 부분수열의 합 2
첫째 줄에 정수의 개수를 나타내는 N과 정수 S가 주어진다. (1 ≤ N ≤ 40, |S| ≤ 1,000,000) 둘째 줄에 N개의 정수가 빈 칸을 사이에 두고 주어진다. 주어지는 정수의 절댓값은 100,000을 넘지 않는다.
www.acmicpc.net
부분수열의 합 자체는 Int 범위라는 것에 낚여서
경우의 수가 최대 2^40 이라는 것을 깜빡했다...
그냥 헷갈리면 long때리자
import java.util.*;
import java.io.*;
public class g1_1208 {
static FastScanner fs = new FastScanner();
static PrintWriter pw = new PrintWriter(System.out);
static int n, s;
public static void main(String[] args) {
n = fs.nextInt();
s = fs.nextInt();
int[] p1 = fs.readArray(n / 2);
int[] p2 = fs.readArray(n - n / 2);
PriorityQueue<Integer> priq1 = new PriorityQueue<>();
PriorityQueue<Integer> priq2 = new PriorityQueue<>(Collections.reverseOrder());
fill(priq1, p1, 0, 0);
fill(priq2, p2, 0, 0);
long cnt = 0, n1 = priq1.poll(), n2 = priq2.poll();
while (true){
if (n1 + n2 == s){
long c1 = 1, c2 = 1;
while (!priq1.isEmpty() && priq1.peek() == n1){
c1++;
priq1.poll();
}
while (!priq2.isEmpty() && priq2.peek() == n2){
c2++;
priq2.poll();
}
cnt+= c1 * c2;
if (priq1.isEmpty() || priq2.isEmpty()) break;
n1 = priq1.poll();
n2 = priq2.poll();
}
else if (n1 + n2 < s){
if (priq1.isEmpty()) break;
n1 = priq1.poll();
}
else{
if (priq2.isEmpty()) break;
n2 = priq2.poll();
}
}
if (s == 0) cnt--;
pw.println(cnt);
pw.close();
}
static void fill(PriorityQueue<Integer> priq, int[] p, int ptr, int sum){
if (ptr == p.length){
priq.add(sum);
return;
}
fill(priq, p, ptr + 1, sum);
fill(priq, p, ptr + 1, sum + p[ptr]);
}
// ----------input function----------
static void sort(int[] a) {
ArrayList<Integer> L = new ArrayList<>();
for (int i : a)
L.add(i);
Collections.sort(L);
for (int i = 0; i < a.length; i++)
a[i] = L.get(i);
}
static class FastScanner {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer("");
String next() {
while (!st.hasMoreTokens()) {
try {
st = new StringTokenizer(br.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
return st.nextToken();
}
int nextInt() {
return Integer.parseInt(next());
}
int[] readArray(int n) {
int[] a = new int[n];
for (int i = 0; i < n; i++)
a[i] = nextInt();
return a;
}
long nextLong() {
return Long.parseLong(next());
}
}
}
'PS > Problems' 카테고리의 다른 글
[Java] 백준 9252번 LCS 2 - LCS (0) | 2022.02.08 |
---|---|
[Java] 백준 1806번 부분합 - 투 포인터 (0) | 2022.02.06 |
[Java] 백준 1202번 보석 도둑 - 우선순위큐 응용 (0) | 2022.02.06 |
[Java] 백준 1197번 최소 스패닝 트리 (0) | 2022.02.05 |
[Java] 백준 11779번 최소비용 구하기 2 - 다익스트라(nlgn) (0) | 2022.02.04 |