작성
·
115
·
수정됨
0
안녕하세요 큰돌님. 항상 좋은 강의 감사드립니다.
7-W에 제가 생각했을때 같은 논리인것 같은데 1%에서 오답으로 떠 질문 드립니다 ㅜㅜ 아래는 제 코드입니다.
#include<bits/stdc++.h>
using namespace std;
int a[100001];
int n;
int dp[100001][5][5];
int go(int idx,int left, int right){
if(idx == n) return 0;
int &ret = dp[idx][left][right];
if(ret!=-1) return ret;
ret = 987654321;
int num = a[idx];
//Left
if(left == 0) ret = min(ret,go(idx+1,num,right)+2);
if(num == left) ret = min(ret,go(idx+1,left,right)+1);
if(abs(left-num)==2) ret = min(ret, go(idx+1,num,right)+4);
if((num+1)%4 == left || (num!=1 && num-1 ==left) || (num==1 && left ==4))ret = min(ret,go(idx+1,num,right)+3);
//Right
if(right == 0) ret = min(ret,go(idx+1,left,num)+2);
if(num == right) ret = min(ret,go(idx+1,left,right)+1);
if(abs(right-num)==2) ret = min(ret,go(idx+1,left,num)+4);
if((num+1)%4 == right || (num!=1 && num-1 ==right) || (num==1 && right ==4)) ret = min(ret,go(idx+1,left,num)+3);
return ret;
}
int main(){
while(true){
int num = 0;
cin>>num;
if(num==0) break;
a[n]=num;
++n;
}
memset(dp,-1,sizeof(dp));
cout<<go(0,0,0)<<"\n";
}
현재 코드에서
//Left
if(left == 0) ret = min(ret,go(idx+1,num,right)+2);
if(num == left) ret = min(ret,go(idx+1,left,right)+1);
if(abs(left-num)==2) ret = min(ret, go(idx+1,num,right)+4);
if((num+1)%4 == left || (num!=1 && num-1 ==left) || (num==1 && left ==4))ret = min(ret,go(idx+1,num,right)+3);
//Right
if(right == 0) ret = min(ret,go(idx+1,left,num)+2);
if(num == right) ret = min(ret,go(idx+1,left,right)+1);
if(abs(right-num)==2) ret = min(ret,go(idx+1,left,num)+4);
if((num+1)%4 == right || (num!=1 && num-1 ==right) || (num==1 && right ==4)) ret = min(ret,go(idx+1,left,num)+3);
부분만 강의코드와 비슷하게 아래와 같이 바꾸면
ret = min(ret, go(idx+1,a[idx],right)+check(left,a[idx]));
ret = min(ret, go(idx+1,left,a[idx])+check(right,a[idx]));
통과가 됩니다... 다른 많은 예제들도 넣어봤는데 잘 돌아가는데 어디서 잘못 짚은걸까요?? ㅠㅠ
답변 2
1
안녕하세요 희수님 ㅎㅎ
우선순위에 따른 로직부분에 대한 미스가 있는 것 같습니다.
예를 들어,
if(left == 0) ret = min(ret,go(idx+1,num,right)+2);
if(num == left) ret = min(ret,go(idx+1,left,right)+1);
이 경우에 left가 0이고 num이 0이라면 두개의 if문이 동시에 작동되지 않을까요? 이 때문에 로직부분에서 미스가 생기는 것이죠.
제가 다듬어봤습니다. 참고부탁드립니다.
#include<bits/stdc++.h>
using namespace std;
int a[100001];
int n;
int dp[100001][5][5];
int go(int idx,int left, int right){
if(idx == n) return 0;
int &ret = dp[idx][left][right];
if(ret!=-1) return ret;
ret = 987654321;
int num = a[idx];
//Left
if(left == 0) ret = min(ret,go(idx+1,num,right)+2);
else if(num == left) ret = min(ret,go(idx+1,num,right)+1);
else if(abs(left-num)==2) ret = min(ret, go(idx+1,num,right)+4);
else ret = min(ret,go(idx+1,num,right)+3);
//Right
if(right == 0) ret = min(ret,go(idx+1,left,num)+2);
else if(num == right) ret = min(ret,go(idx+1,left,num)+1);
else if(abs(right-num)==2) ret = min(ret,go(idx+1,left,num)+4);
else ret = min(ret,go(idx+1,left,num)+3);
return ret;
}
int main(){
while(true){
int num = 0;
cin>>num;
if(num==0) break;
a[n++] = num;
}
memset(dp,-1,sizeof(dp));
cout<<go(0,0,0)<<"\n";
}
또 질문 있으시면 언제든지 질문 부탁드립니다.
좋은 수강평과 별점 5점은 제게 큰 힘이 됩니다. :)
감사합니다.
강사 큰돌 올림.
0
안녕하세요, 인프런 AI 인턴입니다.
말씀하신 코드 부분에서 문제가 발생하는 원인은 check
함수의 구현 방식과 관련된 것으로 보입니다. 코드에서 직접 작성한 조건문들과 check
함수를 사용한 조건문 사이에는 로직을 판단하는 방법에 차이가 있을 수 있습니다.
원래 코드에서는 각 조건에 대해 명시적으로 거리를 계산해서 ret
에 할당하고 있습니다. 반면, check
함수를 사용하는 방식은 left
와 a[idx]
혹은 right
와 a[idx]
사이의 거리를 구하는 로직을 해당 함수 내부에 구현해야 하며, 이 과정에서 조건을 판단하는 방식에 미세한 차이가 발생할 수 있습니다.
예를 들어 check
함수 내에서 거리 계산 로직이 위의 코드에서 처리한 것과 정확히 일치하지 않거나, 예외 사항을 다르게 처리할 수 있기 때문에 결과에 영향을 줄 수 있습니다. 따라서, check
함수 내부 구현을 검토하면서 해당 함수가 각 상황에 맞게 거리를 올바르게 계산하고 있는지 확인해 볼 필요가 있습니다.
구체적인 check
함수의 구현 내용을 제공하지 않았기 때문에 더 자세한 분석은 어렵지만, 일반적으로 이러한 경우 함수 내부의 로직을 점검하여 외부에서 사용했을 때와 내부에서 처리했을 때의 차이점을 찾아보는 것이 좋습니다.
또한, 강의 커뮤니티 질문&답변 게시판을 이용하시면 강사님께서 보다 정확한 답변을 제공해 주실 수도 있습니다.
가능한 모든 수를 고려해야 한다고 생각하여 모든 경우에 if문을 사용하였는데, 이 문제에서는 "양 발"이 어떻게 움직이느냐에 따라 달라지는 문제이므로 left, right로 나눠서 이번턴에 각각 움직였을때 최솟값을 구하면 되는 문제였군요..!
언제나 빠르고 친절한 설명 감사드립니다!!!