본문 바로가기
PS

백준 1744번 C++ 수 묶기

by mtoc 2019. 6. 29.


수 묶기

https://www.acmicpc.net/problem/1744

길이가 N인 수열이 주어졌을 때, 그 수열의 합을 구하려고 한다. 하지만, 그냥 그 수열의 합을 모두 더해서 구하는 것이 아니라, 수열의 두 수를 묶으려고 한다. 어떤 수를 묶으려고 할 때, 위치에 상관없이 묶을 수 있다. 하지만, 같은 위치에 있는 수(자기 자신)를 묶는 것은 불가능하다. 그리고 어떤 수를 묶게 되면, 수열의 합을 구할 때 묶은 수는 서로 곱한 후에 더한다.

예를 들면, 어떤 수열이 {0, 1, 2, 4, 3, 5}일 때, 그냥 이 수열의 합을 구하면 0+1+2+4+3+5 = 15이다. 하지만, 2와 3을 묶고, 4와 5를 묶게 되면, 0+1+(2*3)+(4*5) = 27이 되어 최대가 된다.

수열의 모든 수는 단 한번만 묶거나, 아니면 묶지 않아야한다.

수열이 주어졌을 때, 수열의 각 수를 적절히 묶었을 때, 그 합이 최대가 되게 하는 프로그램을 작성하시오.





도대체 수를 왜 묶냐

음수일 때 고려 안 해서 한 번 틀리고

홀수, 짝수 조건 거꾸로 해서 한 번 더 틀리고

인덱스 잘못 접근해서 한 번 더 틀리고 드디어 맞았다.

그렇다 이 문제는 정렬한 상태에서


1. 원소가 음수이고 해당 인덱스가 짝수일 때

-> 그 원소를 제외한 음수가 짝수개이므로 곱하지 않고 넘어간다(인덱스가 작아질수록 절댓값이 커지므로)

2. 원소와 그 다음 원소를 곱했을 때의 값이 0 이하일 때

-> 경계를 잘 고려해주어야 한다. 이때 해당 인덱스가 홀수고 곱해서 0이 된다면 곱하는 것이 이득

3. 원소와 그 다음 원소를 곱했을 때의 값이 양수일 때(양수*양수, 음수*음수)

-> 무조건 곱하는 게 이득이다.


그리고 1일때는 인덱스 -1, 2와 3일 때는 인덱스 -2 해줘야 한다.

더 효율적인 게 있을지 모르지만 나는 이렇게 풀었다.

역시 돌려봐야 맞을지 틀릴지도 아는데 틀리면서 돌리는 습관은 좀 고쳐야할 듯





코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>
#include <algorithm>
using namespace std;
int main(){
    cin.tie();
    int N;
    cin>>N;
    int series[N], i;
    for(i=0; i<N; i++)
        cin>>series[i];
    if(N==1){
        cout<<series[0];
        return 0;
    }
    //위치에 상관없이 묶을 수 있으므로 정렬
    sort(series, series+N);
    long long sum=0;
    i=N-1;
    while(i>0){
        if(series[i]<0&&i%2==0){
            i--;
            continue;
        }
        if(series[i]*series[i-1]<=0&&i%2==1){
            if(series[i]==0){
                series[i]*=series[i-1];
                series[i-1]=0;
            }
            i=i-2;
            continue;
        }
        //양수*양수, 음수*음수의 경우
        if(series[i]*series[i-1]>0){
            series[i]=max(series[i]+series[i-1], series[i]*series[i-1]);
            series[i-1]=0;
            //i-1번째 원소는 건너뛰어도 됨
            i=i-2;
            continue;
        }
        i--;
    }
    for(i=0; i<N; i++){
        sum+=series[i];
    }
    cout<<sum<<endl;
    return 0;
}
cs


댓글