algorithm

[μ½”λ“œνŠΈλ¦¬ μ‘°λ³„κ³Όμ œ] Preprocessing

rkawk 2024. 7. 24. 11:45

μ‹œκ°„μ„ 쀄일 수 μžˆλŠ” 방법쀑 ν•˜λ‚˜λ‘œ μ„€λͺ…λ˜λŠ” μ „μ²˜λ¦¬μ΄λ‹€.

μ „μ²˜λ¦¬λΌλŠ” λ‹¨μ–΄μ˜ μ˜λ―Έμ™€ 같이 μž…λ ₯받은 데이터에 λŒ€ν•΄ μ„ μ œμ μœΌλ‘œ μ²˜λ¦¬ν•˜μ—¬ 완전탐색을 ν”Όν•  수 μžˆλ„λ‘ ν•˜λŠ” 방법이닀.

 

문제 1) κ΄„ν˜Έ 쌍 λ§Œλ“€μ–΄μ£ΌκΈ°

λ‹¨μˆœ λͺ¨λ“  경우의 수λ₯Ό νƒμƒ‰ν•˜λ©΄ λͺ¨λ“  인덱슀λ₯Ό νƒμƒ‰ν•˜λ©΄μ„œ μ—¬λŠ” κ΄„ν˜Έκ°€ λ‘κ°œμΈ μ‹œμž‘μ μ„ μ°Ύκ³ , λ‹«λŠ” κ΄„ν˜Έκ°€ λ‘κ°œμΈ 끝 점을 μ „λΆ€ μ°Ύμ•„μ„œ ν•΄μ•Όλœλ‹€. μ΄λŠ” (((()))), (())(())와 같은 κ²½μš°κ°€ μ΅œμ•…μ˜ 경우둜 생각할 수 μžˆλŠ”λ°, ((을 작고 ))을 μ°ΎκΈ°μœ„ν•΄ λͺ¨λ“  인덱슀λ₯Ό νƒμƒ‰ν•˜λŠ” κ³Όμ •μ—μ„œ μ‹œκ°„λ³΅μž‘λ„λŠ” O(N^2)κ°€ λ‚˜μ˜€κ²Œ λœλ‹€.

 

sol1) λˆ„μ ν•© μ‘μš© μ „μ²˜λ¦¬

λˆ„μ ν•©μ˜ λŒ€μƒμ„ νŠΉμ • 인덱슀 였λ₯Έμͺ½μ˜ ))의 개수둜 ν•œλ‹€.

 

( ( ) ) ( ( ) ) ( ( ) ) 와 같은 μ˜ˆμ‹œκ°€ μžˆλ‹€κ³  ν•˜μž.

인덱슀의 μ—­μˆœμœΌλ‘œ ))의 λˆ„μ  개수λ₯Ό μ±„μš°λ©΄

3 3 3 2 2 2 2 1 1 1 1 0 이 λœλ‹€.

((와 ))κ°€ μŒμ„ μ΄λ£¨λ―€λ‘œ 처음 μž…λ ₯받은 λ¬Έμžμ—΄μ„ 순차적으둜 νƒμƒ‰ν•˜λ©° ((κ°€ λ‚˜μ˜¬ 경우 λˆ„μ  개수λ₯Ό 전체 정닡에 ν•©ν•΄μ£Όλ©΄ λœλ‹€.

 

#include <iostream>
#include <string>
#include <queue>
#include <algorithm>
using namespace std;
string a;
queue<int>b1, b2;
long long ans;
int main() {
    cin>>a;
    for(int i=1; i<a.size(); i++) {
        if(a[i] == '(' && a[i-1] == '(')
            b1.push(i);
        if(a[i] == ')' && a[i-1] == ')')
            b2.push(i-1);
    }
    while(!b1.empty()) {
        int cur = b1.front(); b1.pop();
        while(b2.front() < cur && !b2.empty()) {
            b2.pop();
        }
        if(b2.empty())
            break;
        ans += b2.size();
    }
    cout<<ans;
    return 0;
}

 

λ‚˜λŠ” ((와 ))κ°€ λ°œμƒν•˜λŠ” 경우의 인덱슀λ₯Ό μ „λΆ€ μ €μž₯ν•˜κ³  )) queue의 frontκ°€ ((의 μΈλ±μŠ€λ³΄λ‹€ μž‘λ‹€λ©΄ λΉΌμ£Όκ³  )) queue의 sizeλ₯Ό λ”ν•˜λŠ” λ°©μ‹μœΌλ‘œ κ΅¬ν˜„ν•˜μ˜€λ‹€.

 

 

문제 2) μ΄μƒν•œ 폭탄

νŠΉμ • 번호λ₯Ό κ°€μ§„ 폭탄이 κ°€μž₯ 졜근 μ–΄λŠ μΈλ±μŠ€μ— μž…λ ₯이 λ“€μ–΄μ™”λŠ”μ§€ 미리 μ²΄ν¬ν•΄λ†“μœΌλ©΄ λœλ‹€.

폭탄은 무쑰건 μˆœμ„œλŒ€λ‘œ λ“€μ–΄μ˜€κ³ , K 거리 이내에 μžˆλŠ” 같은 번호λ₯Ό κ°€μ§„ 폭탄듀은 무쑰건 κ°€μž₯ 졜근 λ“€μ–΄μ˜¨ 폭탄과 연관이 λœλ‹€.

κ·ΈλŸ¬λ―€λ‘œ κ°€μž₯ 졜근 λ“€μ–΄μ˜¨ 같은 번호의 폭탄을 μ²΄ν¬ν•˜κ³ , K μ΄ν•˜μΈμ§€ ν™•μΈν•˜λ©΄ λœλ‹€.

 

#include <iostream>
#include <algorithm>
using namespace std;
int N, K, bomb[1000001], ans;
int main() {
    cin>>N>>K;
    for(int i=1; i<=N; i++) {
        int bnum; cin>>bnum;
        if(!bomb[bnum]) bomb[bnum] = i;
        else if(i - bomb[bnum] <= K) ans = max(ans, bnum);
        else bomb[bnum] = i;
    }
    if(!ans) cout<<-1;
    else cout<<ans;
    return 0;
}

 

문제 3) μ΅œμ†Œ μ—λ„ˆμ§€ λΉ„μš©

그리디 λŠλ‚Œμ˜ 풀이λ₯Ό μš”κ΅¬ν•˜λŠ” λ¬Έμ œμ΄λ‹€.

νŠΉμ • 지점에 λ„λ‹¬ν•˜κΈ° μœ„ν•œ μ΅œμ†Œ μ½”μŠ€νŠΈλŠ” νŠΉμ • 지점 이전에 μžˆλŠ” λ‹€λ₯Έ 지점듀 쀑에 κ°€μž₯ μž‘μ€ μ½”μŠ€νŠΈλ₯Ό κ°€μ§„ μ§€μ μ—μ„œ μ—λ„ˆμ§€λ₯Ό μ±„μ›Œ κ°€μ Έμ˜€λŠ” 방법이닀.

κ·ΈλŸ¬λ―€λ‘œ νŠΉμ • 지점에 ν•΄λ‹Ήν•˜λŠ” μΈλ±μŠ€μ— νŠΉμ • μ§€μ κΉŒμ§€μ˜ λͺ¨λ“  μ§€μ μ˜ μ΅œμ†Œ μ½”μŠ€νŠΈλ₯Ό μ €μž₯ν•˜κ³ , λͺ¨λ“  지점 μ‚¬μ΄μ˜ μ—λ„ˆμ§€ 값을 κ³±ν•΄μ£Όλ©΄ λœλ‹€.

 

#include <iostream>
using namespace std;

long long N, energy[100001], cost[100001], dp[100001], ans;
int main() {
    cin>>N;
    for(int i=0; i<N-1; i++) cin>>energy[i];
    for(int j=0; j<N; j++) cin>>cost[j];
    dp[0] = cost[0];
    for(int i=1; i<N-1; i++) {
        dp[i] = min(cost[i], dp[i-1]);
    }
    for(int i=0; i<N-1; i++) {
        ans += energy[i]*dp[i];
    }
    cout<<ans;
    return 0;
}