출처: https://cses.fi/problemset/task/1746


문제 설명

You know that an array has n integers between 1 and m, and the difference between two adjacent values is at most 1.

Given a description of the array where some values may be unknown, your task is to count the number of arrays that match the description.

입력  

The first input line has two integers n and mm: the array size and the upper bound for each value.

The next line has n integers x_1,x_2,,x_n : the contents of the array. Value 0 denotes an unknown value.

출력 

Print one integer: the number of arrays modulo 10^9+7.

입력 예

3 5
2 0 2

출력 예

3

Explanation: [2,1,2], [2,2,2] , and [2,3,2]

제약조건

  • 1 <= N <= 10^5
  • 1 <= M <= 100
  • 0 <= x_i <= M 

문제 풀이 

배열에서 어떤 위치의 숫자는 바로 전 위치의 숫자 값에 따라서 결정된다(+1, -1, 0). 이렇게 가능한 경우의 배열을 x_0 부터 x_n-1까지 계속해서 더해서 만든다. 단, 이렇게 더하는 과정에 커지는 숫자는 modulo 연산으로 일정하게 만든다.

프로그램 내용

더보기
...
for (int i = 1; i < n; i++)
{
	if( x_i == 0 )	/// update all possible numbers 
	{
		for (int j = 1; j <= m; j++)
		{
			k = min(1, j);
			dp[i][k] += (dp[i-1][k-1] + dp[i-1][k] + dp[i-1][k+1]) % MOD;
		}
	}
	else	/// update x_i
	{
		dp[i][x_i] += (dp[i-1][x_i-1] + dp[i-1][x_i] + dp[i-1][x_i+1]) % MOD;
	}
}
...      

 

Dynamic Programming link )

'CSES' 카테고리의 다른 글

CSES 7. Mathematics  (0) 2020.01.01
CSES 7. Stair Game(1099)  (0) 2020.01.01
CSES 3. Book Shop (1158)  (0) 2019.12.28
CSES 3. Grid Paths (1638)  (0) 2019.12.28
CSES 2. Sliding Cost (1077)  (0) 2019.12.28

출처: https://cses.fi/problemset/1158


문제 설명

You are in a book shop which sells n different books. You know the price and number of pages of each book.

You have decided that the total price of your purchases will be at most x. What is the maximum number of pages you can buy? You can buy each book at most once.

입력 

N X // Number of books, maximum total price

h_i // books price

s_i // number of pages

 

출력

the maximum number of pages.

입력 예 

4 10
4 8 5 3
5 12 8 1

출력 예

13

제약조건

  • 1<= N <= 1000
  • 1<= X <= 1e5
  • 1<= h_i, s_i <= 1000 

문제 풀이 내용

Knapsack 문제이다. 어떤 특정한 책을 선택했을 때 페이지와, 그 책을 고르지 않았을 경우에 얻을 수 있는 페이지의 최대값을 비교해서 큰 값을 선택하도록 한다.

프로그램 내용

더보기
...
    vector<int> pr(n,0);
    vector<int> pg(n,0);
    vector<int> dp(x+1,0);
...
    for (int i = 0; i < n; i++) 
        for (int j = x; j >= 1; j--) 
            if (pr[i] <= j) 
                dp[j] = max(dp[j], dp[j - pr[i]] + pg[i]); 
...

 

Dynamic Programming link )

'CSES' 카테고리의 다른 글

CSES 7. Stair Game(1099)  (0) 2020.01.01
CSES 3. Array Description (1746)  (0) 2019.12.31
CSES 3. Grid Paths (1638)  (0) 2019.12.28
CSES 2. Sliding Cost (1077)  (0) 2019.12.28
CSES 2. Sliding Median (1076)  (0) 2019.12.25

출처: https://cses.fi/problemset/task/1638


문제 설명

Consider an N x N grid whose squares may have traps. It is not allowed to move to a square with a trap.

Your task is to calculate the number of paths from the upper-left square to the lower-right square where you only can move right or down.

입력  

First line: N /// grid size

N line : grid information ( . : empty cell, * : trap)

출력

Print the number of paths modulo 1e9 + 7

입력 예

4
....
.*..
...*
*...

출력 예

3

제약조건

1 <= N <= 1000


문제 풀이 내용

어떤 특정한 cell ( path[i][j] ) 까지 도착하는 경로는 왼쪽에서 온 경우( path[i-1][j])와 위쪽에서 온 경우(path[i][j-1])의 합으로 결정된다. 제일 처음 출발하는 cell부터 목표로 하는 cell 까지 cell이 trap(*)인 경우는 제외하고 더해서 만들어 간다. 

프로그램 내용

더보기
...
    vector <string> maze(n+1);
    for (int i = 1; i <= n; i++)
        string tmp;
        maze[i] = "."+tmp;

    vector <vector<int>> path(n+1, vector<int>(n+1));

    path[1][0] = 1;

    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            if (maze[i][j] == '.')
                path[i][j] = (path[i-1][j]+path[i][j-1]) % M;
...

 

Dynamic Programming link )

'CSES' 카테고리의 다른 글

CSES 3. Array Description (1746)  (0) 2019.12.31
CSES 3. Book Shop (1158)  (0) 2019.12.28
CSES 2. Sliding Cost (1077)  (0) 2019.12.28
CSES 2. Sliding Median (1076)  (0) 2019.12.25
CSES 3. Removing Digits (1637)  (0) 2019.10.14

출처: https://cses.fi/problemset/task/1077


문제 설명

You are given an array of n integers. Your task is to calculate for each window of k elements, from left to right, the minimum total cost of making all elements equal.

You can increase or decrease each element with cost x where x is the difference between the new and the original value. The total cost is the sum of such costs.

입력 

The first input line contains two integers n and k: the number of elements and the size of the window.

Then there are n integers x_1,x_2,,x_n: the contents of the array.

출력  

Output nk+1 values: the costs.

입력 예

8 3
2 4 3 5 8 1 2 1

출력 예

2 2 5 7 7 1

제약조건

  • 1 <= <= n <= 2x10^5
  • 1 <= x_i <= 10^9

문제 풀이 내용

중간값을 출력하는 문제의 확장이다. 다만, 이경우에 윈도우를 움직일때마다 새롭게 변경되는 중간값과 그것을 기준으로 하는 비용을 다시 계산하면, 시간제한에 걸린다. 

바로 직전의 중간값과 비용을 저장하고 있다가, 새로 변경되는 부분만큼만 비용을 갱신하는 방법을 사용한다.

프로그램 내용

더보기
...
    vector<long> num_arr(tN + 1);

    for (int id = 1; id <= tN; ++id)
        cin >> num_arr[id];

	long cost = 0;
    long old_med = 0;
    long med = 0;

    if (tK == 1) 
        for (int id = 1; id <= tN; ++id)
            cout << 0 << " ";
    else
        priority_queue<pair<int, int>, vector<pair<int, int>>, less<pair<int, int>>> lpq;
        priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> rpq;

        long mid = (tK + 1) / 2;
        int w_size = 0;
        for (int id = 1; id <= tN ; ++id) 
            while (!lpq.empty() && lpq.top().second <= id - tK) lpq.pop();
            while (!rpq.empty() && rpq.top().second <= id - tK) rpq.pop();

            if (w_size < mid) 
                rpq.push(make_pair(num_arr[id], id));
                auto tmp = rpq.top();
                rpq.pop();
                lpq.push(tmp);
                ++w_size;
            else 
                lpq.push(make_pair(num_arr[id], id));
                auto tmp = lpq.top();
                lpq.pop();
                rpq.push(tmp);

            while (!lpq.empty() && lpq.top().second <= id - tK) lpq.pop();
            while (!rpq.empty() && rpq.top().second <= id - tK) rpq.pop();

            if (id == tK) 
                old_med = lpq.top().first;
                for (int idn = 1; idn <= tK; ++idn) 
                    cost += abs(num_arr[idn] - old_med);
            else if (id > tK)  
                med = lpq.top().first;

                cost = cost + abs(med - num_arr[id]) - abs(old_med - num_arr[id - tK]);

                if (tK % 2 == 0) cost -= (med - old_med);

                old_med = med;
            else 
                continue;
            if (num_arr[id - tK + 1] <= lpq.top().first) --w_size;
...

 

Sorting and Searching link )

'CSES' 카테고리의 다른 글

CSES 3. Book Shop (1158)  (0) 2019.12.28
CSES 3. Grid Paths (1638)  (0) 2019.12.28
CSES 2. Sliding Median (1076)  (0) 2019.12.25
CSES 3. Removing Digits (1637)  (0) 2019.10.14
CSES 3. Coin Combinations II (1636)  (0) 2019.10.10

출처: https://cses.fi/problemset/task/1076


문제 설명

You are given an array of n integers. Your task is to calculate the median of each window of k elements, from left to right.

The median is the middle element when the elements are sorted. If the number of elements is even, there are two possible medians and we assume that the median is the smaller of them.

입력 

The first input line contains two integers n and k: the number of elements and the size of the window.

Then there are n integers x_1,x_2,,x_n : the contents of the array.

출력 

Print nk+1 values: the medians.

입력 예

8 3
2 4 3 5 8 1 2 1

출력 예

3 4 5 5 2 1

제약조건

  • 1 <= k <= n <= 2x10^5
  • 1 <= x_i <= 10^9

문제 풀이 내용

입력 배열을 읽어 들인다.

- 윈도우 크기가 1인 경우는 배열을 순서대로 출력한다.

- 윈도우의 크기가 배열 크기와 같은 경우에는 정렬하여 중간값을 출력한다.

 

처음에 작성한 알고리즘 - 같은 값이 여러개 있고, 그것들이 중간값인 경우에 잘못된 값을 출력한다.

배열의 앞에서부터 윈도우 크기만큼 multiset 에 넣고, 첫번째 중간값을 출력한다. 새로운 입력값(a), 현재 중간값(b), 삭제할 값(c)을 비교해서, 새로운 중간값을 출력한다.

  • 삭제할 값이 중간값과 같은 경우, 새로운 값의 크기에 따라 중간값 위치를 움직인다
    • a = b, c > b -> b* = b+1, c < b -> b* = b-1
  • 새로운 값과 삭제할 값이 다른 쪽에 위치하면 중간 값을 움직인다. 
    • a < b && c >= b -> b* = b+1,  a >= b && c < b  -> b* = b-1.

변경한 알고리즘 - median을 중심으로 커지는 것과 작아지는 2개의 priority_queue 2개를 사용한다.

입력을 median을 기준으로 작은쪽에 넣고, 양쪽 크기를 비교해서 같도록 값을 옮겨준다. 커지는 queue의 값이 median이 된다.

프로그램 내용

 

같은 값이 여러개 있고, 그것들이 중간값인 경우에 에러가 나오던 소스

더보기
...
    vector <long> num_arr(nNum);

    multiset <long> sub_arr;

    for(int idx=0; idx < nNum; ++idx)
        cin >> num_arr[idx];

    if (wSize == 1)
        for (int idx = 0; idx < nNum; ++idx) 
            cout << num_arr[idx] << " ";
        cout << endl;

        return 0;
    else if (wSize == nNum)
        sort(num_arr.begin(), num_arr.end()); 
        cout << num_arr[(nNum+1) / 2-1] << endl; 
        return 0;
    else
        for (int idx = 0; idx < wSize ; ++idx) 
            sub_arr.insert(num_arr[idx]);

        auto med = sub_arr.begin();

        /// first median
		for (int idx = 0; idx < (wSize-1)/2 ; ++idx)
            ++med;
        cout << *med << " ";

        /// moving window
        for (int idx = wSize, id=0; idx < nNum; ++idx, ++id) 
            sub_arr.insert(num_arr[idx]); 
            
            if (sub_arr.find(num_arr[id]) == med) 
                if ( num_arr[idx] < *med) 
                    --med; 
                else if ( num_arr[idx] >= *med) 
                    ++med; 
            else 
                if (num_arr[id] < *med && num_arr[idx] >= *med) 
                    ++med; 
                else if (num_arr[id] >= *med && num_arr[idx] < *med) 
                    --med; 
           
            sub_arr.erase(sub_arr.find(num_arr[id])); 
            cout << *med << " "; 
...

오름차순, 내림차순으로 priority queue 2개 만들어서 새로운 값들을 넣으면서 중간값을 출력하는 소스

더보기
...
    vector<long> num_arr(tN+1);

    priority_queue<pair<int, int>, vector<pair<int, int>>, less<pair<int, int>>> lpq;
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> rpq;

    long mid = (tK+1)/2 ;
    int w_size = 0;
    for(int id=1; id <= tN;++id)
        cin >> num_arr[id];

		while (!lpq.empty() && lpq.top().second <= id - tK) lpq.pop();
		while (!rpq.empty() && rpq.top().second <= id - tK) rpq.pop();

		if (w_size < mid)
			rpq.push(make_pair(num_arr[id], id));
			auto tmp = rpq.top();
			rpq.pop();
			lpq.push(tmp);
			++w_size;
		else
			lpq.push(make_pair(num_arr[id], id));
			auto tmp = lpq.top();
			lpq.pop();
			rpq.push(tmp);

		while (!lpq.empty() && lpq.top().second <= id - tK) lpq.pop();
		while (!rpq.empty() && rpq.top().second <= id - tK) rpq.pop();

...

 

Sorting and Searching link )

'CSES' 카테고리의 다른 글

CSES 3. Grid Paths (1638)  (0) 2019.12.28
CSES 2. Sliding Cost (1077)  (0) 2019.12.28
CSES 3. Removing Digits (1637)  (0) 2019.10.14
CSES 3. Coin Combinations II (1636)  (0) 2019.10.10
CSES 3. Coin Combinations I (1635)  (0) 2019.10.09

출처: https://www.acmicpc.net/problem/17404


문제 설명

1~N개의 집 칠하는데, 옆집과는 다른 색으로 칠하는데 필요한 최소 비용. 집의 배치는 원형으로 생각해서 첫집과 마지막집이 이웃이 되도록 한다.


입력

집의 수와 각각의 집을 칠하는데 필요한 비용

출력

필요한 최소 비용 

입력 예

3
26 40 83
49 60 57
13 89 99

출력 예

110

제약조건

  • 1<= N <= 1000
  • 1 <= a_i <= 1000

문제 풀이

RGB거리 문제에서 약간의 변형이 있다. 집들의 시작과 끝이 연결되어 초기조건을 한번 정하는 것으로 결정할 수 없도록 변형됐다. 기본 아이디어는 초기조건과 거기에 따른 제한 조건을 만족하는 최소의 값들을 찾어서, 비교하도록 했다.

첫집을 특정한 색으로 칠하는 경우에 그 색을 제외한 다른 색들은 아주 큰값으로 설정해서 다음번 집 계산에서 선택되지 않도록 해서 마지막 집까지 최소값을 구한다. 마지막집을 칠하는 최소값에서 첫집과 같은 색깔로 칠하는 경우는 배제하고 최소값을 구한다.  

프로그램 내용

더보기
const int INF = 987654321;
int tN;

/// 색깔별로 칠하는 최소비용을 계산한다
int minPaint(vector<tuple<int, int, int>>& p_cost, int color);

int main()
{
    cin >> tN;

    /// 각 집을 칠하는 비용 입력
    vector<tuple<int, int, int>> p_cost(tN);
    for(int id=0; id< tN; ++id)
    {
	...
	}

    int cost_r = minPaint(p_cost, 0); // first hosuse red
    int cost_g = minPaint(p_cost, 1); // first hosuse green
    int cost_b = minPaint(p_cost, 2); // first hosuse blue

  	int cost = min({cost_r, cost_g, cost_b}); 

    cout << cost << "\n";

 

관련 문제

 

RGB 거리 (1149)  

'Baekjoon Online Judge' 카테고리의 다른 글

BOJ 23970 알고리즘 수업 - 버블 정렬 3  (0) 2022.02.13
BOJ 2824 최대공약수  (0) 2021.12.03
BOJ 15686 - 치킨 배달  (0) 2020.03.25
BOJ 2903 - 중앙 이동 알고리즘  (0) 2020.01.28

출처: https://cses.fi/problemset/task/1637


문제 설명

You are given an integer n. On each step, you may subtract from it any one-digit number that appears in it.

How many steps are required to make the number equal to 0?

입력 

The only input line has an integer n.

출력

Print one integer: the minimum number of steps.

입력 예

27

출력 예

5

Explanation: An optimal solution is  27 , 20(-7), 18(-2), 10(-8), 9(-1) - 0 (-9)

제약조건

  • 1 <= n <= 10^6

문제 풀이

어떤 수의 자리수 중에서 가장 큰 숫자를 찾아서, 그 숫자들을 계속 빼주는 방법이다. 

최적의 경우의 수는 각 자리의 수를 빼서 나온 수의 경우의 수 +1 중에서 가장 작은 것이 된다. 

 

입력 N 의 크기를 생각해보면, 기록할 필요 없이 가장 큰 자리수를 찾아서 빼내고, 다시 재귀적으로 돌려도 충분할 것 같다.

프로그램 내용

더보기
...
    vector<int> DP(nNum+1, 1e9);

    DP[0] = 0;
    for (int idx=1; idx <= nNum; ++idx)
        int tmp = idx;
        while(tmp)
            int r_digit = tmp % 10;
            DP[idx] = min( DP[idx], DP[idx-r_digit] + 1);
            tmp /= 10;
...

 

Dynamic Programming link )

'CSES' 카테고리의 다른 글

CSES 2. Sliding Cost (1077)  (0) 2019.12.28
CSES 2. Sliding Median (1076)  (0) 2019.12.25
CSES 3. Coin Combinations II (1636)  (0) 2019.10.10
CSES 3. Coin Combinations I (1635)  (0) 2019.10.09
CSES 3. Minimizing Coins (1634)  (0) 2019.10.09

처음 풀이 ( link )


문제 풀이

자물쇠 숫자 3개를 tuple<int, int, int>로 처리하고, 숫자 사이의 차이를 abs 이용해서 계산한다. 다만, modulo 연산에서 -를 지원하지 않기 때문에 dial number - 2 ( modulo -2) 보다 큰 경우도 고려한다. 3중 루프를 O(N^3)이지만 최대 dial number 100 을 생각하면, 속도에 문제가 될 것 같지는 않다. 필요하다면, key number 에서 5x5x5 로 가능한 숫자 배열을 작성하고, 그 배열 숫자들로만 루프를 돌리면 좀 더 빨라질 것 같다. 중복 제거를 위해서 set 에 무조건 입력하고, 중복이 제거된 결과의 수만 조회 했는데, 입력하기 전에 조회를 하고 없으면 입력하도록 하는것도 방법이 될 수는 있을 것 같다. 효율성은 find를 하고 없으면 입력하는것이 조금은 더 좋을 것 같다.

프로그램 내용

더보기
#define MAX_DIAL 100

/// tuple<int, int, int> key vs tuple<int, int, int> dest check
bool check_distance(tuple <int, int, int> key, tuple <int, int, int> dest, int dial_num);
{
    int a, b, c;
    int x, y, z;
    tie(a,b,c) = key;
    tie(x,y,z) = dest;
    int dist1, dist2, dist3;

    dist1 = abs(a-x);    dist2 = abs(b-y);    dist3 = abs(c-z);

    if ((dist1 <= 2 || dist1 >= dial_num-2)
        && (dist2 <= 2 || dist2 >= dial_num-2)
        && (dist3 <= 2 || dist3 >= dial_num-2) )
        return true;
    else
        return false;
}

int main() {
    /// Read requirement
    int dial_num = 0;
    fin >> dial_num;

    int f1, f2, f3;
    fin>> f1 >> f2 >> f3;

    int m1, m2, m3;
    fin>> m1 >> m2 >> m3;

    set <tuple<int,int,int>> c_codes;

    tuple <int, int, int> f_key = make_tuple(f1, f2, f3);
    tuple <int, int, int> m_key = make_tuple(m1, m2, m3);

    for(int id1=0;id1 < dial_num ; ++id1)
        for (int id2 = 0; id2 < dial_num; ++id2)
            for(int id3= 0; id3 < dial_num; ++id3)
                tuple <int, int, int> c_key = make_tuple(id1, id2, id3);
                /// check distance 1d1 with f1/m1, id2 with f2/m2, id3 with f3/m3
                if(check_distance(f_key, c_key, dial_num))
                    c_codes.insert(c_key);
                if(check_distance(m_key, c_key, dial_num))
                    c_codes.insert(c_key);

    if (dial_num < 6)
        fout << dial_num * dial_num * dial_num << endl;
    else
        fout << c_codes.size() << endl;

 

 

Chapter 1. Getting started (link)

출처: https://train.usaco.org/usacogate


문제 설명

Farmer John has three milking buckets of capacity A, B, and C liters. Each of the numbers A, B, and C is an integer from 1 through 20, inclusive. Initially, buckets A and B are empty while bucket C is full of milk. Sometimes, FJ pours milk from one bucket to another until the second bucket is filled or the first bucket is empty. Once begun, a pour must be completed, of course. Being thrifty, no milk may be tossed out. 

Write a program to help FJ determine what amounts of milk he can leave in bucket C when he begins with three buckets as above, pours milk among the buckets for a while, and then notes that bucket A is empty.

입력 

A single line with the three integers A, B, and C.

출력

A single line with a sorted list of all the possible amounts of milk that can be in bucket C when 
bucket A is empty.

입력 예

8 9 10

출력 예

1 2 8 9 10


문제 풀이

water jug problem 이라고 불리는 물통 사이에서 물을 옮기는 문제이다. 여기서는 물통 3개를 이용하므로, 3 water jug problem이라고 할 수 있다. 시작할때 가지고 있는 물의 양(0, 0, C)에서 물통 사이에서 한번에 옮길 수 있는 6가지 경우들을 재귀적으로 검색한다. 한번 검색한 곳은 다시 검색하지 않도록 확인해서, 검색을 종료하도록 한다. 문제 조건에 따라서 물통 A가 비어 있을때 물통 C의 양을 기록해서 출력한다.

프로그램 내용

더보기
#define BUCKET_LIMIT 21

vector <int> record(BUCKET_LIMIT, 0); /// possible amount record
vector <vector <int>> visited(BUCKET_LIMIT, vector<int>(BUCKET_LIMIT,0)); /// mark visit
vector <int> capa(3); /// store bucket status

void pour(int &from, int &to, int cpfrom, int cpto);
void search(int a, int b, int c); /// check all possible case

int main() {
    int A, B, C;
    fin >> A >> B >> C;

/// initial
    /// Bucket A : 0, Bucekt B: 0, Bucket C: full
    capa[0] = A;    capa[1] = B;    capa[2] = C;

    search(0, 0, C);

 

Chapter 1. Getting started ( link )

출처: https://train.usaco.org/usacogate


문제 설명

The cows have not only created their own government but they have chosen to create their own money system. In their own rebellious way, they are curious about values of coinage. Traditionally, coins come in values like 1, 5, 10, 20 or 25, 50, and 100 units, sometimes with a 2 unit coin thrown in for good measure.
The cows want to know how many different ways it is possible to dispense a certain amount of money using various coin systems. For instance, using a system of {1, 2, 5, 10, ...} it is possible to create 18 units several different ways, including: 18x1, 9x2, 8x2+2x1, 3x5+2+1, and many others.
Write a program to compute how many ways to construct a given amount of money using supplied coinage. It is guaranteed that the total will fit into both a signed long long (C/C++) and Int64 (Free Pascal).

입력 양식

The number of coins in the system is V (1 <= V <= 25).
The amount money to construct is N (1 <= N <= 10,000).

Line 1: Two integers, V and N
Lines 2..: V integers that represent the available coins (no particular number of integers per line)

출력

A single line containing the total number of ways to construct N money units using V coins.

입력 예

3 10 
1 2 5

출력 예

10


문제 풀이

특정한 정수 집합으로 원하는 값을 만들어내는 경우의 수를 세는 문제로 coin change 문제이다. 

특정한 코인 값 c[i] =a 라고 하면, 원하는 값 target 를 만들 수 있는 방법은 이 코인이 없이 만들수 있는 경우의 수와 이 코인 값을 제외한 값을 만들수 있는 경우의 수의 합이 된다. 

  ... target - b  ... target ...
coin[i] = a ... ... ... v(target, a) ...
coin[i+1] = b ... v(target - b, b) ... v(target, b) ...

 v(target, b) = v(target, a) + v(target-b, b) 

다만, 이 경우에는 코인의 수는 제한이 없기 때문에, 코인 값의 배수들에 해당하는 값들을 모두 확인해야 한다.

참고: subset sum problem ( link )

프로그램 내용

더보기
int main()
{
    int N, target;
    fin >> N >> target;

    vector<int> coins(N,0);

    for (int id = 0; id < N; ++id) 
        fin >> coins[id]; 

    vector <long long> table(target+1,0);

    sort(coins.begin(), coins.end());

    table[0] = 1;

    for(int id = 0; id < N; ++id) 
        for(int idn = coins[id]; idn <= target; ++idn) 
            table[idn] += table[idn-coins[id]]; 

	if( table[target] != 0) 
        fout << table[target] << '\n'; 
    else 
        fout << -1 << '\n'; 

 

Chapter 2. Bigger Challenges ( link )

'USACO Training' 카테고리의 다른 글

Problem 1.4.6 Combination Lock - 2  (0) 2019.10.13
Problem 1.5.3 Mother's Milk  (0) 2019.10.12
Problem 2.2.4 Subset Sums  (0) 2019.10.10
Problem 2.1.5 Sorting A Three-Valued Sequence  (0) 2019.09.18
Problem 2.1.4 Ordered Fractions  (0) 2019.09.18

+ Recent posts