카테고리 없음
백준온라인 2169번 [로봇 조종하기][C++]
쉽지않네
2021. 3. 16. 20:27
2169번: 로봇 조종하기
첫째 줄에 N, M(1≤N, M≤1,000)이 주어진다. 다음 N개의 줄에는 M개의 수로 배열이 주어진다. 배열의 각 수는 절댓값이 100을 넘지 않는 정수이다. 이 값은 그 지역의 가치를 나타낸다.
www.acmicpc.net
나의 풀이
입력을 받은 배열의 i행 j열 값을 \(d [i][j]\) 라 하고
\(dp[i][j]\) 은 i행 j열 까지 왔을 경우 최대가치라 정의하자
알고리즘은 다음과 같다
- 로봇이 존재하는 0행을 기준으로는 오른쪽 밖에 가지 못하기 때문에 j가 커지는 순으로 \(dp [0][j]\) = \(d [0][j]\) + \(dp [0][j-1]\) 식을 만족한다
- 두 번째 행부터는 "0열에서 m열까지" 순차적으로 한 번 보고 "m열에서 0열까지" 거꾸로 총 두 번을 순회를 하면서
첫 번째 행에서 썼던 방식과 비슷하게 \(dp [i][j]\) = max(위칸에서 얻을 수 최댓 값 , 이전칸에서 얻을수 있는 최댓값(순회 방향 기준)) + \(d [i][j]\) 현재 값을 해주면서 초기화해주면서 두 방식 중 최대의 값을 가지는 \(dp [i][j]\) 값을 최종적으로 저장해주면 된다. - \(d [n][m]\)에 답이 담긴다
탑다운 방식의 경우
dp배열 자체를 \(dp [i][j][방향]\)으로 둔 다음
- 왼쪽, 오른쪽이 정 해지는 순간 계속 그 방향만을 봐야 하기 때문에 방향을 함수의 인자로 전달하여주고
- 0,0 좌표까지 갔을 경우 반환 시작
- 이동하는 게 가능한 좌표인지 판단하고 재귀 호출
코드
bottom-up
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <bits/stdc++.h> | |
using namespace std; | |
using vi = vector<int>; | |
using vvi = vector<vi>; | |
int main(){ | |
ios_base::sync_with_stdio(false); | |
cin.tie(nullptr); | |
int n,m; | |
cin>>n>>m; | |
vvi d(n+1,vi(m+2)); | |
vvi l=d,r=d; | |
for(int i=1;i<=n;i++){ | |
for(int j=1;j<=m;j++){ | |
cin>>d[i][j]; | |
} | |
} | |
for(int i=2;i<=m;i++) | |
d[1][i]+=d[1][i-1]; | |
for(int i=2;i<=n;i++){ | |
r[i][1] = d[i-1][1]+d[i][1]; | |
for(int j=2;j<=m;j++){ | |
r[i][j] = max(r[i][j-1],d[i-1][j])+d[i][j]; | |
} | |
l[i][m] = d[i-1][m]+d[i][m]; | |
for(int j=m-1;j>=0;j--){ | |
l[i][j] = max(l[i][j+1],d[i-1][j])+d[i][j]; | |
} | |
for(int j=1;j<=m;j++){ | |
d[i][j] = max(r[i][j],l[i][j]); | |
} | |
} | |
cout<<d[n][m]; | |
} |
top-down
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <bits/stdc++.h> | |
#define INF 0x3f3f3f3f | |
using namespace std; | |
int d[1001][1001]; | |
int dp[1001][1001][3]; | |
int n,m; | |
bool isPossible(int a,int b){ | |
if(a>=0&&a<n&&b>=0&&b<m)return true; | |
return false; | |
} | |
int go(int r , int c , int dir){ | |
if(r==0&&c==0) | |
return d[r][c]; | |
int &ret = dp[r][c][dir]; | |
if(ret!=-1) | |
return ret; | |
ret =-INF; | |
if(isPossible(r-1,c)) | |
ret = max({ret,go(r-1,c,0),go(r-1,c,1),go(r-1,c,2)}); | |
if(isPossible(r,c-1)&&dir==1) | |
ret = max(ret , go(r,c-1,dir)); | |
if(isPossible(r,c+1)&&dir==2) | |
ret = max(ret , go(r,c+1,dir)); | |
return ret+=d[r][c]; | |
} | |
int main(){ | |
ios_base::sync_with_stdio(false); | |
cin.tie(nullptr); | |
memset(dp,-1,sizeof(dp)); | |
cin>>n>>m; | |
for(int i=0;i<n;i++){ | |
for(int j=0;j<m;j++){ | |
cin>>d[i][j]; | |
} | |
} | |
cout<<max(go(n-1,m-1,0),go(n-1,m-1,1)); | |
} |