ABOUT ME

https://github.com/chongin12 chongin12@naver.com

Today
Yesterday
Total
  • 7. dp - LCS
    SCCC - Soongsil Computing Contest Club/2020 Winter-Study 2020. 1. 21. 13:39
    반응형

    7.md
    0.01MB

    1. 복습

    boj.kr/13301, boj.kr/17391

    1. LCS(Longest Common Subsequence)

    ACAYKP, CAPCAK이 있을 때 최장 공통 부분 문자열을 구해보자.

      A C A Y K P
    C 0 1 1 1 1 1
    A 1 1 2 2 2 2
    P 1 1 2 2 2 3
    C 1 2 2 2 2 3
    A 1 2 3 3 3 3
    K 1 2 3 3 4 4

    dp[i][j] = 첫번째 문자열의 i번째, 두번째 문자열의 j번째까지 봤을 때 가장 긴 공통 부분 문자열

    arr[i] == arr[j] 일 때 dp[i][j] = dp[i-1][j-1] + 1;

    arr[i] != arr[j] 일 때 dp[i][j] = max(dp[i][j-1], dp[i-1][j]);

    참고 문제 : boj.kr/9251, boj.kr/3793, boj.kr/5582, boj.kr/5502, boj.kr/1695, boj.kr/1958, boj.kr/9252, boj.kr/14002/, boj.kr/12852

    1. 부록 : 참고 문제 풀이
    • boj.kr/13301
    #include <iostream>
    using namespace std;
    typedef long long int ll;
    ll arr[100];
    ll dp[100];
    
    int main(){
        ll N; cin >> N;
        arr[1]=1;
        arr[2]=1;
        dp[1]=4;
        dp[2]=6;
    
        for(int i=3; i<=N; ++i){
            arr[i]=arr[i-1]+arr[i-2];
            dp[i]=dp[i-1]+arr[i]*2;
        }
        cout << dp[N] << '\n';
    
    }
    • boj.kr/17391
    #include <iostream>
    using namespace std;
    int arr[301][301];
    int dp[301][301];
    int main(){
        int N, M; cin >> N >> M;
        dp[1][1] = 0;
        for(int i=1; i<=N; ++i){
            for(int j=1; j<=M; ++j){
                cin >> arr[i][j];
                int res=987654321;
    
                for(int k=1; k<=i-1; ++k){
                    if(k+arr[k][j]>=i) res=min(res, dp[k][j]+1);
                }
                for(int k=1; k<=j-1; ++k){
                    if(k+arr[i][k]>=j) res=min(res, dp[i][k]+1);
                }
                if(!(i==1 && j==1)) dp[i][j]=res;
            }
        }
        cout << dp[N][M] << '\n';
    }
    
    //dp[i][j] = i, j가 도착 지점일 때 부스터의 최소 개수
    //dp[i][j] = min(dp[1~i-1][j]+1, dp[i][1~j-1]+1), 단, 이동 가능해야 함.
    • boj.kr/9251
    #include <iostream>
    #include <string>
    using namespace std;
    
    int dp[4001][4001];
    
    int main(){
        string a, b; cin >> a >> b;
        for(int i=0; i<a.size(); ++i){
            for(int j=0; j<b.size(); ++j){
                if(a[i] == b[j]) dp[i+1][j+1] = dp[i][j]+1;
                else dp[i+1][j+1] = max(dp[i][j+1], dp[i+1][j]);
            }
        }
        cout << dp[a.size()][b.size()] << '\n';
    }
    • boj.kr/3793
    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    using namespace std;
    
    int dp[4001][4001];
    
    int main(){
    
        char a[1000], b[1000];
        while(scanf("%s %s", a, b) != EOF){
            for(int i=0; i<=4000; ++i){
                for(int j=0; j<=4000; ++j){
                    dp[i][j] = 0;
                }
            }
            for(int i=0; a[i]!=0; ++i){
                for(int j=0; b[j]!=0; ++j){
                    if(a[i] == b[j]) dp[i+1][j+1] = dp[i][j]+1;
                    else dp[i+1][j+1] = max(dp[i][j+1], dp[i+1][j]);
                }
            }
    
            cout << dp[strlen(a)][strlen(b)] << '\n';
        }
    }
    • boj.kr/5582
    #include <iostream>
    #include <string>
    using namespace std;
    
    int dp[4001][4001];
    int res=-1;
    
    int main(){
        string a, b; cin >> a >> b;
        for(int i=0; i<a.size(); ++i){
            for(int j=0; j<b.size(); ++j){
                if(a[i] == b[j]) dp[i+1][j+1] = dp[i][j]+1;
                else dp[i+1][j+1] = 0;
                res=max(res, dp[i+1][j+1]);
            }
        }
        cout << res << '\n';
    }
    • boj.kr/5502
    #include <iostream>
    #include <string>
    #include <algorithm>
    using namespace std;
    
    int dp[5001][5001];
    
    int main(){
        int N; cin >> N;
        string a; cin >> a;
        string b=a;
        reverse(b.begin(), b.end());
        for(int i=0; i<a.size(); ++i){
            for(int j=0; j<b.size(); ++j){
                if(a[i] == b[j]) dp[i+1][j+1] = dp[i][j]+1;
                else dp[i+1][j+1] = max(dp[i][j+1], dp[i+1][j]);
            }
        }
        cout << a.size()-dp[a.size()][b.size()] << '\n';
    
    }
    • boj.kr/1695
    #include <iostream>
    #include <string>
    #include <algorithm>
    using namespace std;
    
    int dp[5001][5001];
    int a[5001];
    int b[5001];
    
    int main(){
        int N; cin >> N;
        for(int i=1; i<=N; ++i){
            cin >> a[i];
            b[N-i+1] = a[i];
        }
        for(int i=1; i<=N; ++i){
            for(int j=1; j<=N; ++j){
                if(a[i] == b[j]) dp[i][j] = dp[i-1][j-1]+1;
                else dp[i][j]=max(dp[i-1][j], dp[i][j-1]);
            }
        }
        cout << N-dp[N][N] << '\n';
    }
    • boj.kr/1958
    #include <iostream>
    #include <string>
    #define max6(a, b, c, d, e, f) max((a), max((b), max((c), max((d), max((e), (f))))))
    using namespace std;
    int dp[101][101][101];
    int main(){
        string a, b, c; cin >> a >> b >> c;
        for(int i=1; i<=a.size(); ++i){
            for(int j=1; j<=b.size(); ++j){
                for(int k=1; k<=c.size(); ++k){
                    if(a[i-1] == b[j-1] && b[j-1] == c[k-1]) dp[i][j][k] = dp[i-1][j-1][k-1]+1;
                    else dp[i][j][k] = max6(dp[i-1][j][k], dp[i][j-1][k], dp[i][j][k-1], dp[i-1][j-1][k], dp[i][j-1][k-1], dp[i-1][j][k-1]);
                }
            }
        }
        cout << dp[a.size()][b.size()][c.size()] << '\n';
    }
    • boj.kr/9252
    #include <iostream>
    #include <string>
    #include <algorithm>
    using namespace std;
    
    int dp[4001][4001];
    string res = "";
    
    int main(){
        string a, b; cin >> a >> b;
        for(int i=0; i<a.size(); ++i){
            for(int j=0; j<b.size(); ++j){
                if(a[i] == b[j]) dp[i+1][j+1] = dp[i][j]+1;
                else dp[i+1][j+1] = max(dp[i][j+1], dp[i+1][j]);
            }
        }
        cout << dp[a.size()][b.size()] << '\n';
        int i=a.size(), j=b.size();
        while(1) {
            if(dp[i][j] == 0) break;
            if(dp[i-1][j] == dp[i][j]){
                i-=1;
                continue;
            }
            if(dp[i][j-1] == dp[i][j]) {
                j-=1;
                continue;
            }
            res+=a[i-1];
            i-=1; j-=1;
        }
        reverse(res.begin(), res.end());
        cout << res << '\n';
    }
    • boj.kr/14002
    #include <iostream>
    #include <vector>
    using namespace std;
    int arr[1001];
    int dp[1001];
    int maxcnt=-1;
    vector<int> v;
    int main(){
        int N; cin >> N;
        for(int i=1; i<=N; ++i){
            cin >> arr[i];
            if(i==1) dp[i]=1;
            int res=1;
            for(int j=1; j<i; ++j){
                if(arr[i]>arr[j]) res=max(res, dp[j]+1);
            }
            dp[i]=res;
            maxcnt=max(dp[i], maxcnt);
        }
        cout << maxcnt << '\n';
        int key=maxcnt;
        for(int i=N; i>=1; --i){
            if(key==0) break;
            if(dp[i] == key) {
                v.push_back(arr[i]);
                key--;
            }
        }
        for(int i=v.size()-1; i>=0; --i){
            cout << v[i] << " ";
        }
        cout << '\n';
    }
    • boj.kr/12852
    #include <iostream>
    #include <string>
    using namespace std;
    int dp[1000001];
    int solve(int n){
        if(dp[n]) {
            return dp[n];
        }
        if(n==1) {
            return 0;
        }
        if(n%3==0){
            if(n%2==0){
                return dp[n]=min(solve(n/3), min(solve(n/2), solve(n-1)))+1;
            }
            else {
                return dp[n] = min(solve(n/3), solve(n-1))+1;
            }
        }
        else if(n%2==0) {
            return dp[n] = min(solve(n/2), solve(n-1))+1;
        }
        else return dp[n] = solve(n-1)+1;
    }
    int main(){
        int N; cin >> N;
        cout << solve(N) << '\n';
        while(N!=1) {
            if(N%3==0 && dp[N]==dp[N/3]+1){
                cout << N << ' ';
                N/=3;
            }
            else if(N%2==0 && dp[N] == dp[N/2]+1) {
                cout << N << ' ';
                N/=2;
            }
            else{
                cout << N << ' ';
                N-=1;
            }
        }
        cout << "1" << '\n';
    }
    반응형

    'SCCC - Soongsil Computing Contest Club > 2020 Winter-Study' 카테고리의 다른 글

    9. 그래프, dfs, bfs  (0) 2020.02.10
    8. dp - 토글링, 역추적  (0) 2020.01.22
    6. dp : LIS, Knapsack  (0) 2020.01.16
    5. 1차원, 2차원 dp  (0) 2020.01.15
    4. 정수론-소인수분해, gcd, lcm, sieve  (0) 2020.01.14

    댓글

Designed by Tistory.