#include <iostream>
#include <string.h>
#include <string>
#include <algorithm>
using namespace std;
const int MAX_N = 1500;
int N, M;
//누적합보다 메모리가 2배 더소요됨 다음에 재풀이할때는 누적합 방식을 사용할것..
int cache[MAX_N + 1][MAX_N + 1];
int cacheY[MAX_N + 1][MAX_N + 1];
int cacheX[MAX_N + 1][MAX_N + 1];
//string 2차원 배열로 선언
string arr[MAX_N + 1][MAX_N + 1];
int goY[3] = { 1,1,0 };
int goX[3] = { 1,0,1 };
bool isinmap(int y, int x)
{
if (y<1 || y>N || x<1 || x>M)
return false;
return true;
}
//state방향으로 불도저가 지나갔을때, 확정된y줄에있는 모든 사과나무들 합계에넣는다.
//for문 그냥 돌리면 시간초과가 나므로 dp내의dp선언(...)
//처음엔 3차원 cache를 사용했으나 생각해보니 state는 변하지않으므로 2차원만 사용해도 되겠더라
int plusY(int y, int x, int state)
{
if (y > N)
return 0;
if (state == 1)
return 0;
int& ret = cacheY[y][x];
if (ret != -1)
return ret;
if (arr[y + 1][x][0] == 'A' && y+1 <= N)
return ret = plusY(y + 1, x, state) + stoi(arr[y + 1][x].substr(1));
else
return ret = plusY(y + 1, x, state);
}
//plusY함수의 주석과 동일하다.
int plusX(int y, int x, int state)
{
if (x > M)
return 0;
if (state == 2)
return 0;
int& ret = cacheX[y][x];
if (ret != -1)
return ret;
if (arr[y][x + 1][0] == 'B' && x+1 <=M)
return ret = plusX(y, x + 1, state) + stoi(arr[y][x + 1].substr(1));
else
return ret = plusX(y, x + 1, state);
}
//main DP함수. 현재좌표를 값으로갖고 도착점 도착하면 끝.
int go(int y, int x)
{
if (y == N && x == M)
return 0;
int& ret = cache[y][x];
if (ret != -1)
{
return ret;
}
for (int i = 0; i < 3; i++)
{
int nextY = y + goY[i], nextX = x + goX[i];
if (isinmap(nextY, nextX))
{
ret = max(ret, go(nextY, nextX) + plusY(y, x, i) + plusX(y, x, i));
}
}
return ret;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
//1시간 넘어서야 찾아낸 *틀렸습니다*의 원인.. sizeof( )<-안에 들어갈 변수명을 모두 cache로 선언하는 바람에
//근데왜 예제랑 초반테케 몇개를 통과한걸까
//덕분에 int형 long long 형으로 바꾸는 등의 뻘짓을했다.,,
memset(cache, -1, sizeof(cache));
memset(cacheY, -1, sizeof(cacheY));
memset(cacheX, -1, sizeof(cacheX));
cin >> N >> M;
for (int i = 1; i <= N; i++)
for (int j = 1; j <= M; j++)
cin >> arr[i][j];
cout << go(1, 1);
}
https://www.acmicpc.net/problem/3114
3114번: 사과와 바나나
문제 A나라와 B나라가 국경선을 놓고 몇 년째 싸우고 있다. 분쟁 지역의 크기는 직사각형이고, R×C 개의 칸으로 나누어져 있다. 모든 칸에는 사과 나무 또는 바나나 나무가 심어져 잇다. 방금, 기나긴 영토 분쟁을 끝내기 위해 중립국에서 협상가 김상근이 도착했다. 상근이는 불도저를 이용해 일부 칸에 있는 나무를 모두 제거하고, 그러한 칸을 국경선으로 이용하려고 한다. 불도저는 가장 왼쪽 윗칸에서 출발하며, 한 칸 아래, 오른쪽, 오른쪽 아래 대각선으로 이
www.acmicpc.net
정석 풀이법보다 메모리는 3배이상 사용되었다. 아무렴어때.. 내힘으로 푼게 장하다😉
누적합 방식이아니라 그때 그때 계산한다고 내부에 함수를 또 선언한것이 문제였을까?
처음엔 내부의 plusY,plusX함수를 내부에 1500만큼 for문돌렸는데, 당연하게도 시간초과가 났다.
그걸또 시간 줄이겠다고 plusY,plusX함수를 dp처럼 풀었다..
그러다보니 처음으로 dp내의dp함수를 사용해봤는데, 나름 참신했던 방법으로 생각했고..
이렇게 dp내의dp함수 사용하는거 재밌는거같아서, 이런문제나오면 또 올리려한다.
반례찾는다고 Olympiad > Croatian Highschool Competitions in Informatics > 2009 > National Competition #2 - Juniors 구글링해서 테케 다운받아서 돌려보고... cache를 3개 처음써봐서 실수한거라고 생각하긴하는데,
역시 crtl+c ctrl+v 를 코딩에서 쓰는건 하이리스크 하이리턴이다. 오늘일기 끝🙏
'📌BOJ 알고리즘 트레이닝' 카테고리의 다른 글
[BOJ][백준]lazy propagation-17611 직각다각형 (0) | 2019.10.15 |
---|---|
[BOJ][백준]브루트 포스-17610번 양팔저울 (0) | 2019.10.13 |
[BOJ][백준]DP-17528번 Two Machines (0) | 2019.10.10 |
[BOJ][백준]Simulation-17135번 캐슬 디팬스 (0) | 2019.04.11 |
BFS-1600번 말이 되고픈 원숭이 (0) | 2019.04.04 |
#include <iostream>
#include <string.h>
#include <string>
#include <algorithm>
using namespace std;
const int MAX_N = 1500;
int N, M;
//누적합보다 메모리가 2배 더소요됨 다음에 재풀이할때는 누적합 방식을 사용할것..
int cache[MAX_N + 1][MAX_N + 1];
int cacheY[MAX_N + 1][MAX_N + 1];
int cacheX[MAX_N + 1][MAX_N + 1];
//string 2차원 배열로 선언
string arr[MAX_N + 1][MAX_N + 1];
int goY[3] = { 1,1,0 };
int goX[3] = { 1,0,1 };
bool isinmap(int y, int x)
{
if (y<1 || y>N || x<1 || x>M)
return false;
return true;
}
//state방향으로 불도저가 지나갔을때, 확정된y줄에있는 모든 사과나무들 합계에넣는다.
//for문 그냥 돌리면 시간초과가 나므로 dp내의dp선언(...)
//처음엔 3차원 cache를 사용했으나 생각해보니 state는 변하지않으므로 2차원만 사용해도 되겠더라
int plusY(int y, int x, int state)
{
if (y > N)
return 0;
if (state == 1)
return 0;
int& ret = cacheY[y][x];
if (ret != -1)
return ret;
if (arr[y + 1][x][0] == 'A' && y+1 <= N)
return ret = plusY(y + 1, x, state) + stoi(arr[y + 1][x].substr(1));
else
return ret = plusY(y + 1, x, state);
}
//plusY함수의 주석과 동일하다.
int plusX(int y, int x, int state)
{
if (x > M)
return 0;
if (state == 2)
return 0;
int& ret = cacheX[y][x];
if (ret != -1)
return ret;
if (arr[y][x + 1][0] == 'B' && x+1 <=M)
return ret = plusX(y, x + 1, state) + stoi(arr[y][x + 1].substr(1));
else
return ret = plusX(y, x + 1, state);
}
//main DP함수. 현재좌표를 값으로갖고 도착점 도착하면 끝.
int go(int y, int x)
{
if (y == N && x == M)
return 0;
int& ret = cache[y][x];
if (ret != -1)
{
return ret;
}
for (int i = 0; i < 3; i++)
{
int nextY = y + goY[i], nextX = x + goX[i];
if (isinmap(nextY, nextX))
{
ret = max(ret, go(nextY, nextX) + plusY(y, x, i) + plusX(y, x, i));
}
}
return ret;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
//1시간 넘어서야 찾아낸 *틀렸습니다*의 원인.. sizeof( )<-안에 들어갈 변수명을 모두 cache로 선언하는 바람에
//근데왜 예제랑 초반테케 몇개를 통과한걸까
//덕분에 int형 long long 형으로 바꾸는 등의 뻘짓을했다.,,
memset(cache, -1, sizeof(cache));
memset(cacheY, -1, sizeof(cacheY));
memset(cacheX, -1, sizeof(cacheX));
cin >> N >> M;
for (int i = 1; i <= N; i++)
for (int j = 1; j <= M; j++)
cin >> arr[i][j];
cout << go(1, 1);
}
https://www.acmicpc.net/problem/3114
3114번: 사과와 바나나
문제 A나라와 B나라가 국경선을 놓고 몇 년째 싸우고 있다. 분쟁 지역의 크기는 직사각형이고, R×C 개의 칸으로 나누어져 있다. 모든 칸에는 사과 나무 또는 바나나 나무가 심어져 잇다. 방금, 기나긴 영토 분쟁을 끝내기 위해 중립국에서 협상가 김상근이 도착했다. 상근이는 불도저를 이용해 일부 칸에 있는 나무를 모두 제거하고, 그러한 칸을 국경선으로 이용하려고 한다. 불도저는 가장 왼쪽 윗칸에서 출발하며, 한 칸 아래, 오른쪽, 오른쪽 아래 대각선으로 이
www.acmicpc.net
정석 풀이법보다 메모리는 3배이상 사용되었다. 아무렴어때.. 내힘으로 푼게 장하다😉
누적합 방식이아니라 그때 그때 계산한다고 내부에 함수를 또 선언한것이 문제였을까?
처음엔 내부의 plusY,plusX함수를 내부에 1500만큼 for문돌렸는데, 당연하게도 시간초과가 났다.
그걸또 시간 줄이겠다고 plusY,plusX함수를 dp처럼 풀었다..
그러다보니 처음으로 dp내의dp함수를 사용해봤는데, 나름 참신했던 방법으로 생각했고..
이렇게 dp내의dp함수 사용하는거 재밌는거같아서, 이런문제나오면 또 올리려한다.
반례찾는다고 Olympiad > Croatian Highschool Competitions in Informatics > 2009 > National Competition #2 - Juniors 구글링해서 테케 다운받아서 돌려보고... cache를 3개 처음써봐서 실수한거라고 생각하긴하는데,
역시 crtl+c ctrl+v 를 코딩에서 쓰는건 하이리스크 하이리턴이다. 오늘일기 끝🙏
'📌BOJ 알고리즘 트레이닝' 카테고리의 다른 글
[BOJ][백준]lazy propagation-17611 직각다각형 (0) | 2019.10.15 |
---|---|
[BOJ][백준]브루트 포스-17610번 양팔저울 (0) | 2019.10.13 |
[BOJ][백준]DP-17528번 Two Machines (0) | 2019.10.10 |
[BOJ][백준]Simulation-17135번 캐슬 디팬스 (0) | 2019.04.11 |
BFS-1600번 말이 되고픈 원숭이 (0) | 2019.04.04 |