#include <string>
#include <vector>
using namespace std;
int solution(string name) {
int answer = 0;
// 유턴했을 때가 최고의 dist 나올 수 있다.
// ababaaaaaaabaaaaaaaaaaa
// ababaaaaaaabaa
// aaaaaaabab
// abababaaaaaa
// 그냥 오른쪽으로 가는게 좋은 경우
// x y
// abababaaaaaaaaaaaaaaaba
// 첫번재 b발견시 : 2번째 b로 가는 최소 값은 3이다.
// 2번째 b 발견시 : 3번째 b로 가는 최소값은 3이다.
// 3번째 b발견시 : 4번째 b로 가는 최소값은 8이다.
// 그럼 내 생각에는 전부 더해야 하는 걸까?
// 굳이 누적을 해야 할까?
// 어차피 3번째 b로 가는 방법은 idx 로 오른쪽 이동, 다시 왼쪽으로 idx 이동 이후에
// 끝으로 가는 방법이다.
// => 일단 누적을 하지 않음.
// 쉽게 진행하자.
// 0123456789 101112
// aabaaaaaaa b a a : size : 13
// 1번. 그냥 오른쪽으로 쭉 가기
// 2번. 유턴하기
// 아니면 이런것도 있다.
// 뒤를 먼저 갔다가 앞으로 진행.
// 10 (idx + diff) vs 2 + 2 + size() - 1 - 10 + 1
// 8 vs 4 + 2 + 1
// 8 vs 4 + 1
//////////// 아래 걸로 증명 됨.
// 0123456789 10 11 12 13 14 15
// aaaabaaaaa a a a a b b
// 전체 사이즈는 16
// 오른쪽으로 쭉 이동하는 거는 안된다.
// 오른쪽으로 갔다가 다시 u턴하기
// 쭉 오른쪽으로 가기
// 그냥 왼쪽으로 갔다가 다시 원점 지나서 오는거는?
// 오른쪽 가는 거를 x라고 하고 ,
// 왼쪽으로 가는 거를 y라고 하면
// 가) 4 + 4 + 16 - 14
// 나) (16 -14) * 2 + 4
// idx * 2 + size() - nextIdx
// ( size() - nextIdx) * 2 + idx;
// 4번에서 14번으로 가는 방법
// 14번에서 15번으로 가는 방법
// 2개 중에서 매순간 최소값을 선택하기만 하면 된다.
// 왜냐하면 가번을 통해서 이미 오른쪽으로 가는 방법을 통해서 해결된다. 누적할 필요 없다
int minValue = name.size() - 1;
int ssize = name.size();
for(int i = 0; i < name.size(); ++i)
{
// 상하로 이동하는 것만 처리하자.
int up = name[i] - 'A';
int down = 'Z' - name[i] + 1;
answer += min(up, down);
int nextIdx = i + 1;
while(nextIdx < ssize && name[nextIdx] == 'A')
{
nextIdx++;
}
// idx * 2 + size() - nextIdx
// ( size() - nextIdx) * 2 + idx;
int right = i * 2 + ssize - nextIdx;
int left = (ssize - nextIdx) * 2 + i;
minValue = min(minValue, min(right, left));
}
answer += minValue;
return answer;
}
https://4z7l.github.io/2021/03/12/algorithms-prg-42860.html


복귀를 해야 하고,
나를 대상으로 뒤에 오는 value 중에 'a'가 아닌 값을 대상으로 확인하는 식으로 하면 이전에 오는 알파벳에 대해 생각할 필요 없다.
-> 이미 완료된 상태다.
2번째 나오는 b로 이동을 한다고 하자. 그러면 굳이 1번째 나오는 b의 왼쪽, 오른쪽 이동에 대해서 생각할 필요 없다.
핵심!
- 빨간색 1번과 2번을 비교하고 있는데, b에 대해서는 생각할 필요가 없다.
- 나중에 2번을 가지고 다음 pos에 오는 거를 확인할 것이다. 굳이 필요 없다!
-> 규칙성이 보이면 수식화하려는 습관을 갖자.
잘못된 풀이

반례가 있다.
: 한쪽으로만 가능 코드로 하면 안된다. 이때는 유턴하는 것이 효율적이다.

결론 : 반례를 먼저 생각해보고 접근해야 한다.
- 나의 생각인 2번과 3번에 대한 반례를 생각하는 시간을 가져야 한다.

- 자리 이동하는 거 cur위치에서 타겟 자리로 좌측이동 vs 우측 이동한 값의 최소값을 구하고,
- 알파벳을 위로 이동 vs 아래로 이동 최소값을 구한다
- 1번과 2번의 값을 더한 값을 dp값에 넣어주고.
- 최종으로 다 더해주는 방법으로 진행했다.
// 반례

지금 내가 만든 반복문으로는 순차적으로 밖에 진행하지 못하지만,
반례를 보면 0번 인덱스 마치고, 마지막 인덱스로 이동해서 진행하는 것이
최소화 할 수 있다.
이 부분을 생각하지 못해서 만점아님..
추후에 다시 풀자...