Junior-Developer
Home
  • Category (316)
    • 문제풀이 (270)
      • 백준oj (201)
      • 프로그래머스 (53)
      • 명품 자바 프로그래밍(개정4판) (11)
      • 구름 (5)
    • 알고리즘 (6)
    • Node.js (2)
    • 체크리스트 (37)
블로그 내 검색
Home

Junior-Developer

1일 1커밋! 1일 1 백준!

  • 문제풀이/백준oj

    [백준OJ] 18427번 함께 블록 쌓기

    2021. 3. 11.

    by. Hyeon-Uk

    반응형

    www.acmicpc.net/problem/18427

     

    18427번: 함께 블록 쌓기

    첫째 줄에 자연수 N, M, H가 공백을 기준으로 구분되어 주어진다. (1 ≤ N ≤ 50, 1 ≤ M ≤ 10, 1 ≤ H ≤ 1,000) 둘째 줄부터 N개의 줄에 걸쳐서 각 학생이 가진 블록들의 높이가 공백을 기준으로 구

    www.acmicpc.net


     

    풀이)

    dp문제+배낭문제이다. dp[i][j]=k 를 i명이 h높이를 만들 수 있는 경우의 수를 k라고 하자. 

    i명의 사람이 j높이 만큼 쌓을 수 있는 경우의 수는, i-1명이  j-(i번째 사람이 들고있는 현재블록의 높이) 만큼 쌓을 수 있는 경우의 수와 동일하다.

    예를들어 4번째 사람이 들고있는 블록의 높이가 2,4라고 했을 때, 4명의 사람이 10만큼의 높이를 쌓는 경우의 수는 3명이 8만큼 쌓은 경우의 수+3명이 6만큼 쌓은 경우의 수가 된다.

    왜냐하면 3명이 8만큼쌓고 4번째사람이 2를 올렸을때 10이되고, 3명이 6만큼 쌓고 4번째 사람이 4를 올렸을때 10이 되기 때문이다.

    따라서 dp[i][j]=dp[i][j]+dp[i-1][j-(i번째 사람이 들고있는 블록의 높이)] 가 된다.

     

     

    시간 복잡도)

    O(N*M*H)

     

    코드)

    #include<iostream>
    #include<algorithm>
    #include<string>
    using namespace std;
    
    int n,m,h;
    vector<int> v[51];
    int dp[51][1001]={0};//dp[i][j]=k, i명이 h를 만들수 있는 경우의수 k
    
    
    //수행시간 O(n*m*h)
    void solve(){
        //0을 만드는 경우는 모두 1개씩
        for(int i=0;i<=n;i++){
            dp[i][0]=1;
        }
        
        for(int i=1;i<=n;i++){
            for(int j=1;j<=h;j++){
                for(int k=0;k<v[i].size();k++){
                    //사람이 한명 더 줄은 상태의 j-v[i][k]높이의 경우의수를  모두 더해준다.
                    if(j-v[i][k]>=0){
                        dp[i][j]+=dp[i-1][j-v[i][k]];
                        dp[i][j]%=10007;
                    }
                }
                //i번째 사람이 안들어갔을때도 완성이 될 수 있으므로 더해준다
                dp[i][j]+=dp[i-1][j];
                dp[i][j]%=10007;
            }
        }
        
    }
    
    int main() {
        ios_base :: sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
        cin>>n>>m>>h;
        cin.ignore(1);
        for(int i=1;i<=n;i++){
            string data;
            getline(cin,data);
            int temp=0;
            for(int j=0;j<data.size();j++){
                if(data[j]==' '){
                    v[i].push_back(temp);
                    temp=0;
                }
                else{
                    temp=temp*10+(data[j]-'0');
                }
            }
            if(temp!=0)    v[i].push_back(temp);
        }
        
        solve();
        cout<<dp[n][h]<<"\n";
    	return 0;
    }
    

     

    반응형
    저작자표시 (새창열림)

    '문제풀이 > 백준oj' 카테고리의 다른 글

    [백준OJ] 13904번 과제  (0) 2021.03.15
    [백준OJ] 7562번 나이트의 이동  (0) 2021.03.11
    [백준OJ] 2473번 세 용액  (0) 2021.03.09
    [백준OJ] 2467번 용액  (0) 2021.03.09
    [백준OJ] 1715번 카드 정렬하기  (0) 2021.03.09

    댓글

    관련글

    • [백준OJ] 13904번 과제 2021.03.15
    • [백준OJ] 7562번 나이트의 이동 2021.03.11
    • [백준OJ] 2473번 세 용액 2021.03.09
    • [백준OJ] 2467번 용액 2021.03.09
    맨 위로
전체 글 보기
Tistory 로그인
Tistory 로그아웃
로그아웃 글쓰기 관리

Today

Total

Powered by ⓒ Kakao Corp.

Designed by Nana
블로그 이미지
Hyeon-Uk

티스토리툴바