2 3 5 8 ... 피보나치

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
bool vipsit[41];
long long dp[43];
void cal_part() {
       dp[0] = 1; // 이거 해주는 이유는 vip가 두번 연속 나왔을 때 0
으로 초기화 되어 있으면 값이 0이 되므로 1을 해줘도 전체적인 값에 영향은 없다 .
       dp[1] = 1;     
       dp[2] = 2;
       for (int i = 3; i <= 43; ++i) {
               dp[i] = dp[i-1] + dp[i-2];
       }
}
void print_part() {
       for (int i = 1; i <= 100; ++i) {
               cout << dp[i] << ' ';
       }
       cout << endl;
}
int main(void) {
       int n;
       cin >> n;
       int t;
       cin >> t;
       cal_part();
       //print_part();
       for (int i = 0; i < t; ++i) {
               int k;
               cin >> k;
               vipsit[k] = true;
       }
       int ans = 1;
       int cnt = 0;
       for (int i = 1; i <= n; ++i) {
               if (vipsit[i] == true) {
                      ans *= dp[cnt];
                      cnt = 0;
               }
               else {
                      cnt++;
               }
       }
       if (cnt > 0) {
               ans *= dp[cnt];
       }
       cout << ans << endl;
       return 0;
       
}// 123 4 56 7 89
    // 3 * 2 * 2


'알고리즘' 카테고리의 다른 글

[DP] 백준 1495 기타리스트  (0) 2018.04.29
[DP] 백준 2240 자두나무  (0) 2018.04.29
[DP] 백준 1932 숫자삼각형  (0) 2018.04.29
[DP] 백준 14501 퇴사  (0) 2018.04.29
[DP] 백준 1520 내리막길  (0) 2018.04.29


유형은 거의 비슷했고 max안에서 d[i-1][j-1]을 d[i-1][j+1]로 생각해서 조금 해맸었다. 
감으로 하지말고 종이로 생각하면서 하니까 문제점을 찾을 수 있었다. 
메모리랑 시간이 좀 효율적이지 못하다는 것을 보여주는데 나중에 배열을 덜 쓰던가 해서 수정해 보자.

#include <iostream>
#define max(a,b) ((a)>(b) ? (a) : (b))
using namespace std;
int d[501][501];
int sample[501][501];
int main() {
        int n;
        cin >> n;
        for (int i = 1; i <= n; ++i) {
               for (int j = 1; j <= i; ++j) {
                       cin >> sample[i][j];
               }
        }
        d[1][1] = sample[1][1];
        for (int i = 2; i <= n; ++i) {
               for (int j = 1; j <= i; ++j) {
                       d[i][j] += max((d[i - 1][j] + sample[i][j]), (d[i - 1][j - 1] + sample[i][j]));
               }
        }
        int ans = 0;
        for (int j = 1; j <= n; ++j) {
               if (ans < d[n][j])
                       ans = d[n][j];
        }
        cout << ans;
        return 0;
}



'알고리즘' 카테고리의 다른 글

[DP] 백준 2240 자두나무  (0) 2018.04.29
[DP] 백준 2302 극장 좌석  (0) 2018.04.29
[DP] 백준 14501 퇴사  (0) 2018.04.29
[DP] 백준 1520 내리막길  (0) 2018.04.29
[DP] 백준 9251 LCS  (0) 2018.04.29


#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int day[1001];
int val[1001];
int dp[1001];
int n; //n 일까지
int go(int idx) {
       /*cout << idx << endl;*/
       if (idx > n) {
               return 0;
       }
       int& ret = dp[idx];
       if (ret != -1) {
               return ret;
       }
       if (idx + day[idx] <= n+1) { // 8일째에 3일일하라고 하면 10일까지 일하는 거니까 +1을 하던 가 -1을 하던가
               ret = max(go(idx + day[idx]) + val[idx], go(idx + 1));
       }
       else {
               ret = go(idx + 1);
       }
       
       return ret;
}
int main(void) {
       memset(dp, -1, sizeof(dp));
       cin >> n;
       // i 가 의미하는 것 : i일째
       for (int i = 1; i <= n; ++i) {
               cin >> day[i];
               cin >> val[i];
       }// input 끝
       cout << go(1) << endl; //1일차 시작
       /*for (int i = 1; i <= n; ++i) {
               cout << dp[i] << ' ';
       }*/
       return 0;
       
}

'알고리즘' 카테고리의 다른 글

[DP] 백준 2302 극장 좌석  (0) 2018.04.29
[DP] 백준 1932 숫자삼각형  (0) 2018.04.29
[DP] 백준 1520 내리막길  (0) 2018.04.29
[DP] 백준 9251 LCS  (0) 2018.04.29
[DP] 백준 10942 팰린드롬?  (0) 2018.04.29


#include <iostream>
#include <algorithm>
#include <cstring>
#include <limits.h>
#include <string>
using namespace std;
int arr[501][501];
int n, m, cnt = 0;
bool visit[501][501];
int aa = 0;
void go(int x, int y,int before) {
       if (x == n - 1 && y == m - 1) {
              cnt++;
              return;
       }
       if (before <= arr[x][y]) {
              return;
       }
       if (x > n - 1 || y > m - 1 || y<0) {
              return;
       }
       
       /*if (aa == 10) { 경로확인용 test 코드
              aa = 0;
              cout << endl;
       }
       cout << arr[x][y] << ' ';
       aa++;*/
       go(x + 1, y, arr[x][y]);
       go(x, y+1, arr[x][y]);
       go(x, y-1, arr[x][y]);
       go(x - 1, y, arr[x][y]);
}
int main(void)
{
       
       cin >> n >> m;
       for (int i = 0; i < n; ++i) {
              for (int j = 0; j < m; ++j) {
                     cin >> arr[i][j];
              }
       }
       go(0,0,INT_MAX);
       cout << cnt << endl;
       
       return 0;
}
 
완전탐색으로 구현 => 시간초과
Memoization 을 어떻게 해야할 지 모르겠다. 

dfs로 

#include <iostream>
#include <algorithm>
#include <cstring>
#include <limits.h>
#include <string>

using namespace std;

int arr[501][501];
int n, m, cnt = 0;
int d[501][501];
int aa = 0;
int dx[4] = { 1,-1,0,0 };
int dy[4] = { 0,0,-1,1 };


int go(int x, int y) {
    if (x == n - 1 && y == m - 1) {
        return 1;
    }
    if (d[x][y] != -1) {
        return d[x][y];
    }

    int& ans = d[x][y]+=1;
    for (int k = 0; k < 4; ++k) {
        int nx = x + dx[k];
        int ny = y + dy[k];
        if (0 <= nx && nx < n && 0 <= ny && ny < m) {
            if (arr[nx][ny] < arr[x][y]) {
                ans += go(nx, ny);
            }
        }
    }
    return ans;

}

int main(void)
{
    memset(d, -1, sizeof(d));
    cin >> n >> m;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            cin >> arr[i][j];
        }
    }
    
    cout << go(0, 0) << endl;
    
    return 0;
}




'알고리즘' 카테고리의 다른 글

[DP] 백준 1932 숫자삼각형  (0) 2018.04.29
[DP] 백준 14501 퇴사  (0) 2018.04.29
[DP] 백준 9251 LCS  (0) 2018.04.29
[DP] 백준 10942 팰린드롬?  (0) 2018.04.29
[DP] 백준 1890 점프, 3372 보드 점프 다시풀만한 것  (0) 2018.04.29

 
LCS
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
using namespace std;
int main(void)
{
       int LCS_length = 0, max;
       int **table;
       string a, b;
       cin >> a >> b;
       a = "0" + a;
       b = "0" + b;
       int len1, len2;
       len1 = a.length();
       len2 = b.length();
       table = new int*[len2];
       for (int i = 0; i < len2; ++i) {
              table[i] = new int[len1];
       }
       for (int i = 0; i < len1; ++i) {
              table[0][i] = 0; //table에서 첫번째 열 초기화
       }
       for (int i = 1; i < len2; ++i) {
              max = 0;
              table[i][0] = 0;
              for (int j = 1; j < len1; ++j) {
                     if (a[j] == b[i]) {
                           max = table[i - 1][j - 1] + 1;
                           table[i][j] = max;
                     }
                     else {
                           if (table[i][j - 1] > table[i - 1][j])
                                  table[i][j] = table[i][j - 1];
                           else
                                  table[i][j] = table[i - 1][j];
                     }
              }
              if (LCS_length < max)
                     LCS_length = max;
       }
       cout << LCS_length << endl;
       return 0;
}

참고한 곳 

'알고리즘' 카테고리의 다른 글

[DP] 백준 14501 퇴사  (0) 2018.04.29
[DP] 백준 1520 내리막길  (0) 2018.04.29
[DP] 백준 10942 팰린드롬?  (0) 2018.04.29
[DP] 백준 1890 점프, 3372 보드 점프 다시풀만한 것  (0) 2018.04.29
[DP] 백준 2096 내려가기  (0) 2018.04.29

ios_base... 을 안해주면 시간초과가 났던 문제
처음에 for문으로 돌려도 시간초과 안날 것 같아서 해봤는데 시간초과가 났다. 
근데 DP로 짜니 for문보다 훨씬 빠르고 깔끔하게 짜졌다. 좀 익숙해 진 것 같다. 

#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std;
int tb[2001];
int cache[2001][2001];
int go(int a, int b) {
       if (b - a<1) {
              return 1;
       }
       if (cache[a][b] != -1) {
              return cache[a][b];
       }
       int& ret = cache[a][b] = 0;
       if (tb[a] == tb[b]) {
              ret = go(a + 1, b - 1);
       }
       else {
              ret = 0;
       }
       return ret;
}
int main(void)
{
       ios_base::sync_with_stdio(false);
       cin.tie(NULL);
       memset(cache, -1, sizeof(cache));
       int n;
       cin >> n;
       for (int i = 0; i<n; ++i) {
              cin >> tb[i];
       }
       int t;
       cin >> t;
       while (t--) {
              int a, b;
              cin >> a >> b;
              cout << go(a - 1, b - 1) << '\n';
       }
       return 0;
}


마지막까지 간 횟수를 세면 된다고 생각해서 전역변수 cnt 를 기저사례안에서 ++시키면 구할 수 있을 것이라고 생각했다. 
하지만 실제로 저 기저사례를 방문하는 횟수가 가능한 개수가 아니라 그 기저사례를 방문하기 전에 cache에 저장된 값이 기저사례에 방문하기 이전에 방문한 값을 저장하고 있다면
실제로 기저사례는 방문하지 않으면서 cache는 그 경우를 처리한다. 

참조적 투명 함수에 대해 생각하고 전역변수는 최대한 안 쓰고 해결할 수 있게 해봐야 겠다. 

아래 보드 점프 문제는 똑같은데 제한이 2^63-1 보다 큰 것도 온다. BigInt 라이브러리를 가지고 와서 사용했다. 


//1890 점프
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
ll tb[1001][1001]; // tb == table
ll cch[1001][1001]; // cch == cache
ll n, cnt = 0;
ll go(ll x, ll y) {
       if (x == y && y == n - 1) {
              return 1;
       }
       /*if (tb[x][y] == 0) {
       cch[x][y] = -1;
       }*/
       ll& ret = cch[x][y];
       if (ret != -1) {
              return ret;
       }
       ret = 0;
       ll next = tb[x][y];
       if (next > 0) {
              if (x + next < n) {
                     ret += go(x + next, y);
              }
              if (y + next < n) {
                     ret += go(x, y + next);
              }
       }
       return ret;
}
void process() {
       cin >> n;
       for (int i = 0; i < n; ++i) {
              for (int j = 0; j < n; ++j) {
                     cin >> tb[i][j];
                     cch[i][j] = -1; // cahce init
              }
       }
       //cout << (cch[n-1][n-1]==1 ? "YES" : "NO") << endl;
       cout << go(0, 0) << endl;
       return;
}
int main(void)
{
       process();
       return 0;
}

#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
#include <stdlib.h>
#include <string>
using namespace std;
// Big Int 구현 library
typedef int64_t ll;
//typedef long long int ll;
typedef pair<ll, ll> lll;
typedef pair<ll, int> lli;
typedef pair<int, int> ii;
#define EL printf("\n")
#define OK printf("OK")
#define pb push_back
#define mp make_pair
#define ep emplace_back
#define X  first
#define Y  second
#define fillchar(a,x) memset(a, x, sizeof(a))
#define FOR(i,l,r) for (int i=l;i<=r;i++)
#define FORD(i,r,l) for (int i=r;i>=l;i--)
const int base = 1e9;
typedef vector<int> BigInt;
void Set(BigInt &a) {
       while (a.size() > 1 && a.back() == 0) a.pop_back();
}
void Print(BigInt a) {
       Set(a);
       printf("%d", (a.size() == 0) ? 0 : a.back());
       FORD(i, a.size() - 2, 0) printf("%09d", a[i]); EL;
}
BigInt Integer(string s) {
       BigInt ans;
       if (s[0] == '-') return ans;
       if (s.size() == 0) { ans.pb(0); return ans; }
       while (s.size() % 9 != 0) s = '0' + s;
       for (int i = 0; i<s.size(); i += 9) {
              int v = 0;
              for (int j = i; j<i + 9; j++) v = v * 10 + (s[j] - '0');
              ans.insert(ans.begin(), v);
       }
       Set(ans);
       return ans;
}
BigInt Integer(char c[]) {
       string s = "";
       FOR(i, 0, strlen(c) - 1) s = s + c[i];
       return Integer(s);
}
BigInt Integer(ll x) {
       string s = "";
       while (x > 0) s = char(x % 10 + '0') + s, x /= 10;
       return Integer(s);
}
BigInt Integer(int x) {
       return Integer((ll)x);
}
void operator >> (istream &in, BigInt &a) {
       string s;
       getline(cin, s);
       a = Integer(s);
}
void operator << (ostream &out, BigInt a) {
       Print(a);
}
bool operator < (BigInt a, BigInt b) {
       Set(a);
       Set(b);
       if (a.size() != b.size()) return (a.size() < b.size());
       FORD(i, a.size() - 1, 0)
              if (a[i] != b[i]) return (a[i] < b[i]);
       return false;
}
bool operator > (BigInt a, BigInt b) {
       return (b < a);
}
bool operator == (BigInt a, BigInt b) {
       return (!(a < b) && !(b < a));
}
bool operator <= (BigInt a, BigInt b) {
       return (a < b || a == b);
}
bool operator >= (BigInt a, BigInt b) {
       return (b < a || b == a);
}
bool operator < (BigInt a, int b) {
       return (a < Integer(b));
}
bool operator > (BigInt a, int b) {
       return (a > Integer(b));
}
bool operator == (BigInt a, int b) {
       return (a == Integer(b));
}
bool operator >= (BigInt a, int b) {
       return (a >= Integer(b));
}
bool operator <= (BigInt a, int b) {
       return (a <= Integer(b));
}
BigInt max(BigInt a, BigInt b) {
       if (a > b) return a;
       return b;
}
BigInt min(BigInt a, BigInt b) {
       if (a < b) return a;
       return b;
}
BigInt operator + (BigInt a, BigInt b) {
       Set(a);
       Set(b);
       BigInt ans;
       int carry = 0;
       FOR(i, 0, max(a.size(), b.size()) - 1) {
              if (i < a.size()) carry += a[i];
              if (i < b.size()) carry += b[i];
              ans.pb(carry%base);
              carry /= base;
       }
       if (carry) ans.pb(carry);
       Set(ans);
       return ans;
}
BigInt operator + (BigInt a, int b) {
       return a + Integer(b);
}
BigInt operator ++ (BigInt &a) { // ++a
       a = a + 1;
       return a;
}
void operator += (BigInt &a, BigInt b) {
       a = a + b;
}
void operator += (BigInt &a, int b) {
       a = a + b;
}
BigInt operator - (BigInt a, BigInt b) {
       Set(a);
       Set(b);
       BigInt ans;
       int carry = 0;
       FOR(i, 0, a.size() - 1) {
              carry += a[i] - (i < b.size() ? b[i] : 0);
              if (carry < 0) ans.pb(carry + base), carry = -1;
              else ans.pb(carry), carry = 0;
       }
       Set(ans);
       return ans;
}
BigInt operator - (BigInt a, int b) {
       return a - Integer(b);
}
void operator -- (BigInt &a) { // --a
       a = a - 1;
}
void operator -= (BigInt &a, BigInt b) {
       a = a + b;
}
void operator -= (BigInt &a, int b) {
       a = a - b;
}
BigInt operator * (BigInt a, BigInt b) {
       Set(a);
       Set(b);
       BigInt ans;
       ans.assign(a.size() + b.size(), 0);
       FOR(i, 0, a.size() - 1) {
              ll carry = 0ll;
              for (int j = 0; j<b.size() || carry > 0; j++) {
                     ll s = ans[i + j] + carry + (ll)a[i] * (j<b.size() ? (ll)b[j] : 0ll);
                     ans[i + j] = s % base;
                     carry = s / base;
              }
       }
       Set(ans);
       return ans;
}
BigInt operator * (BigInt a, int b) {
       return a * Integer(b);
}
void operator *= (BigInt &a, BigInt b) {
       a = a * b;
}
void operator *= (BigInt &a, int b) {
       a = a * b;
}
BigInt operator / (BigInt a, BigInt b) {
       Set(a);
       Set(b);
       if (b == Integer(0)) return Integer("-1");
       BigInt ans, cur;
       FORD(i, a.size() - 1, 0) {
              cur.insert(cur.begin(), a[i]);
              int x = 0, L = 0, R = base;
              while (L <= R) {
                     int mid = (L + R) >> 1;
                     if (b*Integer(mid) > cur) {
                           x = mid;
                           R = mid - 1;
                     }
                     else
                           L = mid + 1;
              }
              cur = cur - Integer(x - 1)*b;
              ans.insert(ans.begin(), x - 1);
       }
       Set(ans);
       return ans;
}
BigInt operator / (BigInt a, int b) {
       Set(a);
       BigInt ans;
       ll cur = 0ll;
       FORD(i, a.size() - 1, 0) {
              cur = (cur*(ll)base + (ll)a[i]);
              ans.insert(ans.begin(), cur / b);
              cur %= b;
       }
       Set(ans);
       return ans;
}
void operator /= (BigInt &a, BigInt b) {
       a = a / b;
}
void operator /= (BigInt &a, int b) {
       a = a / b;
}
BigInt operator % (BigInt a, BigInt b) {
       Set(a);
       Set(b);
       if (b == Integer(0)) return Integer("-1");
       BigInt ans;
       FORD(i, a.size() - 1, 0) {
              ans.insert(ans.begin(), a[i]);
              int x = 0, L = 0, R = base;
              while (L <= R) {
                     int mid = (L + R) >> 1;
                     if (b*Integer(mid) > ans) {
                           x = mid;
                           R = mid - 1;
                     }
                     else
                           L = mid + 1;
              }
              ans = ans - Integer(x - 1)*b;
       }
       Set(ans);
       return ans;
}
int operator % (BigInt a, int b) {
       Set(a);
       if (b == 0) return -1;
       int ans = 0;
       FORD(i, a.size() - 1, 0)
              ans = (ans*(base%b) + a[i] % b) % b;
       return ans;
}
void operator %= (BigInt &a, BigInt b) {
       a = a % b;
}
void operator %= (BigInt &a, int b) {
       a = a % Integer(b);
}
BigInt gcd(BigInt a, BigInt b) {
       Set(a);
       Set(b);
       while (b > Integer(0)) {
              BigInt r = a % b;
              a = b;
              b = r;
       }
       Set(a);
       return a;
}
BigInt lcm(BigInt a, BigInt b) {
       return (a*b / gcd(a, b));
}
BigInt sqrt(BigInt a) {
       BigInt x0 = a, x1 = (a + 1) / 2;
       while (x1 < x0) {
              x0 = x1;
              x1 = (x1 + a / x1) / 2;
       }
       return x0;
}
BigInt pow(BigInt a, BigInt b) {
       if (b == Integer(0)) return Integer(1);
       BigInt tmp = pow(a, b / 2);
       if (b % 2 == 0) return tmp * tmp;
       return tmp * tmp * a;
}
BigInt pow(BigInt a, int b) {
       return pow(a, (Integer(b)));
}
int log(int n, BigInt a) { // log_n(a)
       Set(a);
       int ans = 0;
       while (a > Integer(1)) {
              ans++;
              a /= n;
       }
       return ans;
}
// Big Int 구현 library 끝
int tb[1001][1001]; // tb == table
BigInt cch[1001][1001]; // cch == cache
int n, cnt = 0;
BigInt go(int x, int y) {
       if (x == y && y == n - 1) {
              return Integer(1);
       }
       /*if (tb[x][y] == 0) {
       cch[x][y] = -1;
       }*/
       BigInt& ret = cch[x][y];
       if (ret != Integer(-1)) {
              return ret;
       }
       ret = Integer(0);
       int next = tb[x][y];
       if (next > 0) {
              if (x + next < n) {
                     ret += go(x + next, y);
              }
              if (y + next < n) {
                     ret += go(x, y + next);
              }
       }
       return ret;
}
void process() {
       cin >> n;
       for (int i = 0; i < n; ++i) {
              for (int j = 0; j < n; ++j) {
                     cin >> tb[i][j];
                     cch[i][j] = Integer(-1); // cahce init
              }
       }
       //cout << (cch[n-1][n-1]==1 ? "YES" : "NO") << endl;
       Print(go(0, 0));
       return;
}
int main(void)
{
       process();
       return 0;
}


'알고리즘' 카테고리의 다른 글

[DP] 백준 9251 LCS  (0) 2018.04.29
[DP] 백준 10942 팰린드롬?  (0) 2018.04.29
[DP] 백준 2096 내려가기  (0) 2018.04.29
[DP] 백준 9507 Generations of Tribbles  (0) 2018.04.29
[DP] 백준 1309 동물원  (0) 2018.04.29

Top-down 구현.
문제에서 메모리 제한이 4MB 
메모리 초과가 나서 이 문제에선 사용할 수 없다. 

최대로 더해가는 DP와 최소로 더해가는 DP를 보려면 이 코드를 보면 될 것 같다. 
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <cstring>
using namespace std;
int tb[100001][3];
int che[100001][3];
int n;
int go(int line, int loca) {
       if (line == n) {
              return 0;
       }
       
       if (che[line][loca] != -1) {
              return che[line][loca];
       }
       int& ret = che[line][loca] = tb[line][loca];
       if (loca == 0) {
              for (int i = 0; i < 2; ++i) {
                     ret = max(ret, go(line + 1, i) + tb[line][loca]);
              }
       }
       if (loca == 1) {
              for (int i = 0; i < 3; ++i) {
                     ret = max(ret, go(line + 1, i) + tb[line][loca]);
              }
       }
       if (loca == 2) {
              for (int i = 1; i < 3; ++i) {
                     ret = max(ret, go(line + 1, i) + tb[line][loca]);
              }
       }
       return ret;
}
int go2(int line, int loca) {
       if (line == n) {
              return 0;
       }
       if (che[line][loca] != -1) {
              return che[line][loca];
       }
       int& ret = che[line][loca] = tb[line][loca];
       //cout << ret << '\n';
       if (loca == 0) {
              for (int i = 0; i < 2; ++i) {
                     ret =go2(line + 1, i) + tb[line][loca];
              }
       }
       if (loca == 1) {
              for (int i = 0; i < 3; ++i) {
                     ret = go2(line + 1, i) + tb[line][loca];
              }
       }
       if (loca == 2) {
              for (int i = 1; i < 3; ++i) {
                     ret = go2(line + 1, i) + tb[line][loca];
              }
       }
       return ret;
}
int main(void)
{
       ios_base::sync_with_stdio(false);
       cin.tie(NULL);
       memset(che, -1, sizeof(che));
       cin >> n;
       for (int i = 0; i < n; ++i) {
              for (int j = 0; j < 3; ++j) {
                     cin >> tb[i][j];
              }
       }
       int ans = -1;
       for (int i = 0; i < 3; ++i) {
              ans = max(ans, go(0, i));
       }
       cout << ans << ' ';
       memset(che, -1, sizeof(che));
       
       ans = INT32_MAX;
       for (int i = 0; i < 3; ++i) {
              ans = min(ans, go2(0, i));
       }
       /*
       for debugging
       for (int i = 0; i < n; ++i) {
              for (int j = 0; j < 3; ++j) {
                     cout << mche[i][j] << ' ';
              }
              cout << '\n';
       }*/
       cout << ans << endl;
       return 0;
}


bottom up 방식으로 해서 모든 결과를 저장해두지 않고 필요한 만큼 저장해 두었다. 

#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <cstring>
using namespace std;
int n;
int tb[3];
int che[3][3];
int mche[3][3];
int main(void)
{
       ios_base::sync_with_stdio(false);
       cin.tie(NULL);
       for (int i = 0; i < 3; ++i) {
              che[1][i] = -1;
              mche[1][i] = INT32_MAX;
       }
       int n;
       cin >> n;
       for (int i = 0; i < n; ++i) {
              for (int j = 0; j < 3; ++j) {
                     cin >> tb[j];
              }
              
              if (i == 0) {
                     for (int k = 0;  k < 3; ++k) {
                           che[i][k] = tb[k];
                           mche[i][k] = tb[k];
                     }
              }
              else {
                     for (int k = 0; k < 2; ++k) {
                           che[1][0] = max(che[1][0], che[0][k] + tb[0]);
                           mche[1][0] = min(mche[1][0],mche[0][k] + tb[0]);
                     }
                     for (int k = 0; k < 3; ++k) {
                           che[1][1] = max(che[1][1], che[0][k] + tb[1]);
                           mche[1][1] = min(mche[1][1], mche[0][k] + tb[1]);
                     }
                     for (int k = 1; k < 3; ++k) {
                           che[1][2] = max(che[1][2], che[0][k] + tb[2]);
                           mche[1][2] = min(mche[1][2], mche[0][k] + tb[2]);
                     }
                     for (int k = 0; k < 3; ++k) {
                           che[0][k] = che[1][k];
                           mche[0][k] = mche[1][k];
                           che[1][k] = -1;
                           mche[1][k] = INT32_MAX;
                     }
              }
       }
       int ans = 0;
       for (int i = 0; i < 3; ++i) {
              ans = max(ans, che[0][i]);
       }
       cout << ans << ' ';
       ans = INT32_MAX;
       for (int i = 0; i < 3; ++i) {
              ans = min(ans, mche[0][i]);
       }
       cout << ans << endl;
       return 0;
}


#include <iostream>
#include <vector>
#include <limits.h>
#include <string>
#include <algorithm>
#include <cstring>
using namespace std;
// Big Int 구현 library
typedef int64_t ll;
//typedef long long int ll;
typedef pair<ll, ll> lll;
typedef pair<ll, int> lli;
typedef pair<int, int> ii;
#define EL printf("\n")
#define OK printf("OK")
#define pb push_back
#define mp make_pair
#define ep emplace_back
#define X  first
#define Y  second
#define fillchar(a,x) memset(a, x, sizeof(a))
#define FOR(i,l,r) for (int i=l;i<=r;i++)
#define FORD(i,r,l) for (int i=r;i>=l;i--)
const int base = 1e9;
typedef vector<int> BigInt;
void Set(BigInt &a) {
       while (a.size() > 1 && a.back() == 0) a.pop_back();
}
void Print(BigInt a) {
       Set(a);
       printf("%d", (a.size() == 0) ? 0 : a.back());
       FORD(i, a.size() - 2, 0) printf("%09d", a[i]); EL;
}
BigInt Integer(string s) {
       BigInt ans;
       if (s[0] == '-') return ans;
       if (s.size() == 0) { ans.pb(0); return ans; }
       while (s.size() % 9 != 0) s = '0' + s;
       for (int i = 0; i<s.size(); i += 9) {
              int v = 0;
              for (int j = i; j<i + 9; j++) v = v * 10 + (s[j] - '0');
              ans.insert(ans.begin(), v);
       }
       Set(ans);
       return ans;
}
BigInt Integer(char c[]) {
       string s = "";
       FOR(i, 0, strlen(c) - 1) s = s + c[i];
       return Integer(s);
}
BigInt Integer(ll x) {
       string s = "";
       while (x > 0) s = char(x % 10 + '0') + s, x /= 10;
       return Integer(s);
}
BigInt Integer(int x) {
       return Integer((ll)x);
}
void operator >> (istream &in, BigInt &a) {
       string s;
       getline(cin, s);
       a = Integer(s);
}
void operator << (ostream &out, BigInt a) {
       Print(a);
}
bool operator < (BigInt a, BigInt b) {
       Set(a);
       Set(b);
       if (a.size() != b.size()) return (a.size() < b.size());
       FORD(i, a.size() - 1, 0)
              if (a[i] != b[i]) return (a[i] < b[i]);
       return false;
}
bool operator > (BigInt a, BigInt b) {
       return (b < a);
}
bool operator == (BigInt a, BigInt b) {
       return (!(a < b) && !(b < a));
}
bool operator <= (BigInt a, BigInt b) {
       return (a < b || a == b);
}
bool operator >= (BigInt a, BigInt b) {
       return (b < a || b == a);
}
bool operator < (BigInt a, int b) {
       return (a < Integer(b));
}
bool operator > (BigInt a, int b) {
       return (a > Integer(b));
}
bool operator == (BigInt a, int b) {
       return (a == Integer(b));
}
bool operator >= (BigInt a, int b) {
       return (a >= Integer(b));
}
bool operator <= (BigInt a, int b) {
       return (a <= Integer(b));
}
BigInt max(BigInt a, BigInt b) {
       if (a > b) return a;
       return b;
}
BigInt min(BigInt a, BigInt b) {
       if (a < b) return a;
       return b;
}
BigInt operator + (BigInt a, BigInt b) {
       Set(a);
       Set(b);
       BigInt ans;
       int carry = 0;
       FOR(i, 0, max(a.size(), b.size()) - 1) {
              if (i < a.size()) carry += a[i];
              if (i < b.size()) carry += b[i];
              ans.pb(carry%base);
              carry /= base;
       }
       if (carry) ans.pb(carry);
       Set(ans);
       return ans;
}
BigInt operator + (BigInt a, int b) {
       return a + Integer(b);
}
BigInt operator ++ (BigInt &a) { // ++a
       a = a + 1;
       return a;
}
void operator += (BigInt &a, BigInt b) {
       a = a + b;
}
void operator += (BigInt &a, int b) {
       a = a + b;
}
BigInt operator - (BigInt a, BigInt b) {
       Set(a);
       Set(b);
       BigInt ans;
       int carry = 0;
       FOR(i, 0, a.size() - 1) {
              carry += a[i] - (i < b.size() ? b[i] : 0);
              if (carry < 0) ans.pb(carry + base), carry = -1;
              else ans.pb(carry), carry = 0;
       }
       Set(ans);
       return ans;
}
BigInt operator - (BigInt a, int b) {
       return a - Integer(b);
}
void operator -- (BigInt &a) { // --a
       a = a - 1;
}
void operator -= (BigInt &a, BigInt b) {
       a = a + b;
}
void operator -= (BigInt &a, int b) {
       a = a - b;
}
BigInt operator * (BigInt a, BigInt b) {
       Set(a);
       Set(b);
       BigInt ans;
       ans.assign(a.size() + b.size(), 0);
       FOR(i, 0, a.size() - 1) {
              ll carry = 0ll;
              for (int j = 0; j<b.size() || carry > 0; j++) {
                     ll s = ans[i + j] + carry + (ll)a[i] * (j<b.size() ? (ll)b[j] : 0ll);
                     ans[i + j] = s % base;
                     carry = s / base;
              }
       }
       Set(ans);
       return ans;
}
BigInt operator * (BigInt a, int b) {
       return a * Integer(b);
}
void operator *= (BigInt &a, BigInt b) {
       a = a * b;
}
void operator *= (BigInt &a, int b) {
       a = a * b;
}
BigInt operator / (BigInt a, BigInt b) {
       Set(a);
       Set(b);
       if (b == Integer(0)) return Integer("-1");
       BigInt ans, cur;
       FORD(i, a.size() - 1, 0) {
              cur.insert(cur.begin(), a[i]);
              int x = 0, L = 0, R = base;
              while (L <= R) {
                     int mid = (L + R) >> 1;
                     if (b*Integer(mid) > cur) {
                           x = mid;
                           R = mid - 1;
                     }
                     else
                           L = mid + 1;
              }
              cur = cur - Integer(x - 1)*b;
              ans.insert(ans.begin(), x - 1);
       }
       Set(ans);
       return ans;
}
BigInt operator / (BigInt a, int b) {
       Set(a);
       BigInt ans;
       ll cur = 0ll;
       FORD(i, a.size() - 1, 0) {
              cur = (cur*(ll)base + (ll)a[i]);
              ans.insert(ans.begin(), cur / b);
              cur %= b;
       }
       Set(ans);
       return ans;
}
void operator /= (BigInt &a, BigInt b) {
       a = a / b;
}
void operator /= (BigInt &a, int b) {
       a = a / b;
}
BigInt operator % (BigInt a, BigInt b) {
       Set(a);
       Set(b);
       if (b == Integer(0)) return Integer("-1");
       BigInt ans;
       FORD(i, a.size() - 1, 0) {
              ans.insert(ans.begin(), a[i]);
              int x = 0, L = 0, R = base;
              while (L <= R) {
                     int mid = (L + R) >> 1;
                     if (b*Integer(mid) > ans) {
                           x = mid;
                           R = mid - 1;
                     }
                     else
                           L = mid + 1;
              }
              ans = ans - Integer(x - 1)*b;
       }
       Set(ans);
       return ans;
}
int operator % (BigInt a, int b) {
       Set(a);
       if (b == 0) return -1;
       int ans = 0;
       FORD(i, a.size() - 1, 0)
              ans = (ans*(base%b) + a[i] % b) % b;
       return ans;
}
void operator %= (BigInt &a, BigInt b) {
       a = a % b;
}
void operator %= (BigInt &a, int b) {
       a = a % Integer(b);
}
BigInt gcd(BigInt a, BigInt b) {
       Set(a);
       Set(b);
       while (b > Integer(0)) {
              BigInt r = a % b;
              a = b;
              b = r;
       }
       Set(a);
       return a;
}
BigInt lcm(BigInt a, BigInt b) {
       return (a*b / gcd(a, b));
}
BigInt sqrt(BigInt a) {
       BigInt x0 = a, x1 = (a + 1) / 2;
       while (x1 < x0) {
              x0 = x1;
              x1 = (x1 + a / x1) / 2;
       }
       return x0;
}
BigInt pow(BigInt a, BigInt b) {
       if (b == Integer(0)) return Integer(1);
       BigInt tmp = pow(a, b / 2);
       if (b % 2 == 0) return tmp * tmp;
       return tmp * tmp * a;
}
BigInt pow(BigInt a, int b) {
       return pow(a, (Integer(b)));
}
int log(int n, BigInt a) { // log_n(a)
       Set(a);
       int ans = 0;
       while (a > Integer(1)) {
              ans++;
              a /= n;
       }
       return ans;
}
// Big Int 구현 library 끝
int tb[10001];
BigInt cch[10001];
int minsum = INT32_MAX;
int n;
BigInt go(int n) {
       if (n == 0) {
              cch[0] = Integer(1);
              return Integer(1);
       }
       if (n == 1) {
              cch[1] = Integer(1);
              return Integer(1);
       }
       if (n == 2) {
              cch[2] = Integer(2);
              return Integer(2);
       }
       if (n == 3) {
              cch[3] = Integer(4);
              return Integer(4);
       }
       BigInt& ret = cch[n];
       if (cch[n] != Integer(-1)) {
              return cch[n];
       }
       ret = Integer(0);
       ret = go(n - 1) + go(n - 2) + go(n - 3) + go(n - 4);
       return ret;
}
int main(void)
{
       for (int i = 0; i < 68; ++i) {
              cch[i] = Integer(-1);
       }
       go(67);
       int t;
       cin >> t;
       while (t--) {
              int k;
              cin >> k;
              Print(cch[k]);
       }
       
       return 0;
}



놓을 수 있는 건 1번 경우와 같이 X, 왼, 오

이렇게 3개 다 놓으려면 가장 아랫줄이 빈칸이어야 한다.
 그 외의 경우에는 2개를 놓을 수 있다.
빈칸인 경우는 n-2와 같다. 왜냐하면 빈칸은 모든 경우에 한번씩 들어가므로 n-1을 만들기위해 사용한 n-2에서 하나씩 만들어 졌기 때문
그외의 경우의 개수는 n-1에서 n-2의 경우를 빼준 것과 같다. 그 경우는 *2씩 해주면 되므로 

마이너스의 모듈러 연산에서는 연산결과가 -가 될 수 있기 때문에 그 경우 mod를 더해줘야 한다. 

#include <iostream>
#include <algorithm>
#include <cstring>
#include <limits.h>
#include <stack>
using namespace std;
typedef long long ll;
ll stb[10001]; // single table
ll sche[100001]; // single cache
int tb[1001][1001];
int cache[1001][1001];
int n,m;
const int mod = 9901;
int main(void) {
       
       cin >> n;
       sche[0] = 1;
       sche[1] = 3;
       for (int i = 2; i <= n; ++i) {
              
              int wow = sche[i - 1] - sche[i - 2];
              if (wow < 0) {
                     wow += mod;
              }
              
              sche[i] = (sche[i-2]*3)%mod  + (2*(wow))%mod;
       }
       cout << sche[n]%mod;
       
       
       return 0;
}


'알고리즘' 카테고리의 다른 글

[DP] 백준 2096 내려가기  (0) 2018.04.29
[DP] 백준 9507 Generations of Tribbles  (0) 2018.04.29
[DP] 백준 2225 합분해 (개수가 주어진 문제)  (0) 2018.04.29
[DP] 백준 1965 상자넣기  (0) 2018.04.29
[DP] 백준 9084 동전  (0) 2018.04.29

+ Recent posts