n으로 나눌 수있는 최대 합


16

StackOverflow 에서이 질문 했지만 여기에 더 적절한 장소가 있다고 생각합니다.

이것은 알고리즘 소개 과정 에서 발생하는 문제입니다 .

양의 정수 가 n 인 배열 가 있습니다 (배열을 정렬하거나 요소를 고유하게 할 필요는 없습니다). 추천 O ( N ) 로 나누어 소자의 가장 큰 합을 찾는 알고리즘 N을 .anO(n)n

예 : . 답은 56입니다 (요소 6 , 13 , 4 , 8 , 25 포함 )a=[6,1,13,4,9,8,25],n=7566,13,4,8,25

동적 프로그래밍을 사용하고 나머지 0 , 1 , 2 , 와 함께 가장 큰 합계를 저장하여 에서 비교적 쉽게 찾을 수 있습니다 . . . , n - 1 .O(n2)0,1,2,...,n1

또한 연속 된 요소 시퀀스에주의를 제한하면 부분 합 모듈로 n 을 저장 하여 시간 에 최적의 시퀀스를 쉽게 찾을 수 있습니다 . let S [ i ] = a [ 0 ] + a [ 1 ] + + a [ i ] , 각 나머지 r 에 대해 S [ j ] r이 되도록 가장 큰 인덱스 j를 기억하십시오O(n)nS[i]=a[0]+a[1]++a[i]rj , 다음의 각 I 고려해야 S [ J ] - S가 [ I ] 여기서, J는 에 대응하는 인덱스이고 , R = S [ I ] 개조 N .S[j]r(modn)iS[j]S[i]jr=S[i]modn

그러나 일반적인 경우에 시간 솔루션이 있습니까? 모든 제안을 부탁드립니다! 나는 이것이 선형 대수를 다루는 것으로 생각하지만 정확히 무엇인지 모르겠습니다.O(n)

또는 시간 내에이 작업을 수행 할 수 있습니까?O(nlogn)


2
1. 스택 오버플로에 똑같은 질문을 게시했습니다. 제발 여러 사이트에서 동일한 질문을 게시하지 않습니다 . 여러 SE 사이트에서 여러 복사본이 떠 다니는 것을 원하지 않습니다. 수용 가능한 답변을 얻지 못한 경우 다른 사이트로 이전하도록 질문을 표시해도되지만 다른 곳에 동일한 내용을 다시 게시하지 마십시오. 2. 교과서 또는 교과서에 대한 참조 / 인용 / 링크를 제공 할 수 있습니까? -시간 솔루션 이 존재 하는가? O(n)
DW

5
당신의 대학에 대한 도전은 여전히 ​​열려 있습니까? 과정에 대한 링크, 정확한 질문을 보는 것이 정말 도움이 될 것이며 실제로 이고 준비한 사람들은 답변을 설명 / 게시 할 것입니다. O(n)
Evil

동적 프로그래밍을 사용하고 나머지 0,1,2, ..., n-10,1,2, ..., n-1과 함께 가장 큰 합계를 저장하여 O (n2) O (n2)에서 비교적 쉽게 찾을 수 있습니다. 좀 더 자세히 설명해 주시겠습니까? 연속 요소 만 고려하지만 비 연속 요소를 고려하면 이것이 n 제곱이되는 방법을 이해할 수 있습니다.
행복을 추구하는 Nithish 추구

답변:


4

다음은 몇 가지 임의의 아이디어입니다.

  • 동적 프로그래밍 알고리즘을 뒤집어 가장 큰 합계 대신 가장 작은 합계를 찾을 수 있습니다. 당신은 하나의 합동에 0 대신에, 전체 배열의 나머지에 합한 합을 찾는다. 요소를 오름차순으로 처리하면 전체 배열을 처리하기 전에 동적 알고리즘이 종료 될 수 있습니다.

    k 개의 요소를 처리하면 비용은 입니다. 있다 없다 의 하한 Ω ( N 로그 N ) 우리는 모든 요소를 정렬 할 필요가 없기 때문에이 알고리즘에. k 개의 가장 작은 요소 를 얻는 데 O ( n log k ) 시간 만 걸립니다 .O(nk)kΩ(nlogn)O(nlogk)k

  • 가장 큰 크기의 집합 대신 큰 크기의 집합을 염두에두면 빠른 푸리에 변환 기반 다항식 곱셈을 사용하여 시간. 도메인 범위가 제한 될 때 3SUM 에서 수행 한 것과 유사합니다 . (참고 : 사용은 다른 당신이 얻을 것이다, 이진 검색을 할 제곱 반복 O ( N K ( 로그 N ) ( 로그 로그 N ) ) KO(n(logn)2(loglogn))O(nk(logn)(loglogn))k 생략 된 요소의 수입니다.)

  • 복합이며, 거의 모든 나머지 중 하나의 배수이다 N 의 요인 상당한 시간이 그 요소의 배수가 아닌 나머지에 초점을 맞춤으로써 저장 될 수 있습니다.nn

  • 잔차 r가 매우 흔하거나 잔재가 거의없는 경우 '여기에서 시작하면 다음 열린 슬롯을 추적하고 r정보를 계속 사용하여 정보를 계속 유지 '하면 많은 점프 스캔 대 오픈 스팟을 저장할 수 있습니다. 시각.

  • 도달 가능성 만 추적하고 플립 된 동적 알고리즘에서 비트 마스크를 사용한 다음 대상 나머지에 도달하면 역 추적 하여 로그 요소면도 할 수 있습니다 .

  • 동적 프로그래밍 알고리즘은 병렬로 실행될 수 있습니다. 각 버퍼 슬롯에 대한 프로세서를 사용하면 까지 내려갈 수 있습니다 . 또는 O ( n 2 ) 폭을 사용하고 반복 집계 대신 집계를 분할 및 정복함으로써 회로 깊이 비용을 O ( log 2 n ) 까지 줄일 수 있습니다 .O(n)O(n2)O(log2n)

  • (메타) 나는 당신이 겪은 문제가 연속적인 합 에 관한 것이라고 강력히 의심합니다 . 실제 문제와 연결되어 있으면 쉽게 확인할 수 있습니다. 그렇지 않으면이 문제가 "알고리즘 소개"라는 과정에서 배정 된 것을 감안할 때이 문제가 얼마나 어려운지 매우 놀랐습니다. 그러나 어쩌면 당신은 그것을 사소하게 만드는 트릭을 다루었습니다.


포인트 1 문제의 사양으로 작성되지 않았으므로 가정 할 수 없습니다. 또한 문제는 배열을 수정하거나 새 배열을 만들 수 없다고 말하는 것이 아닙니다. 실제로 할 수 있습니다. 당신이해야 할 유일한 것은 함께 합산 된 숫자가 O ( n ) 시간 복잡성 에서 으로 나눌 수있는 가장 큰 합을 제공하는 것입니다 (일반적으로 시간 복잡성이라고 가정). nO(n)
nbro

2
@EvilJS 나머지가 0 인 가장 큰 합계를 가진 부분 집합은 나머지가 가장 작은 합계를 가진 부분 집합을 전체 집합의 합계에 합한 후 전체 집합과 같습니다. 합치되는 가장 작은 합을 찾는 것이 r 2에 합치하는 가장 큰 합을 찾는 것보다 더 편리합니다 . 계속 진행하는 대신 솔루션 (처리 요소가 증가 할 때)을 찾 자마자 종료 할 수 있기 때문입니다. r1r2
Craig Gidney

-1

내가 제안한 알고리즘은 다음과 같습니다.

n의 배수 인 summand 만 추가하면 합은 n으로 나눌 수 있습니다.

시작하기 전에 int를 키로, 인덱스 목록을 값으로 사용하여 해시 맵을 작성하십시오. 또한 색인이 포함 된 결과 목록을 만듭니다.

그런 다음 배열을 반복하고 mod n이 0 인 모든 인덱스를 결과 목록에 추가합니다. 다른 모든 색인에 대해 다음을 수행하십시오.

이 인덱스의 값 mod n을 n에서 뺍니다. 이 결과는 필요한 값을 가진 요소의 인덱스를 저장하는 해시 맵의 핵심입니다. 이제이 색인을 해시 맵의 목록에 추가하고 계속 진행하십시오.

배열을 반복 한 후 출력을 계산합니다. 인덱스가 가리키는 값에 따라 해시 맵의 각 목록을 정렬하면됩니다. 이제 해시 맵의 모든 쌍이 n까지 합산되는 것을 고려하십시오. 따라서 n = 7이면 해시 맵에서 3과 4를 검색합니다. 둘 다에 항목이 있으면 두 개의 가장 큰 값을 가져 와서 목록에서 제거하고 결과 목록에 추가합니다.

마지막 권장 사항 : 여전히 알고리즘을 테스트하지 않았고 무차별 강제 알고리즘을 사용하여 테스트 케이스를 작성하십시오.


2
욕심, 선형, 작동하지 않습니다. n으로 나눌 수 있고 쌍으로 n으로 나눌 수있는 요소 만 고려하면 3 배 이상은 어떻습니까? 사소한 경우에는 최대 부분 집합 합계를 보장하지 않습니다. [2, 1, 8]-> 최대 합은 9이지만 알고리즘은 3을 반환합니다.
Evil

@EvilJS 당신의 하위2연산?
델타-종결 기

이 실수를 지적 해 주셔서 감사합니다. 개선에 대한 나의 생각은 값을 증가시켜 정렬 된 목록 스택의 해시 맵을 만들고 배열을 통과 한 후에 만 ​​누적을 시작하는 것입니다.
Tobias Würfl

정렬되는 배열의 배열을 의미하며 "hashmap"이 % n입니까? 당신은 여전히 ​​그것들을 정렬해야하고, 당신이 그것들을 정렬했다면, 최소 / 최대 값을 취하는 것은 괜찮습니다. 그러나 실제로 서브셋을 선택하는 것의 불가피한 부분이 있습니다. 최악의 경우에는 이점이 없습니다. 어쨌든 개선 사항이 있다면 게시물을 편집 할 수 있습니까?
Evil

예, 스택에 대한 매우 빠른 아이디어였습니다. 실제로 정렬 한 해시 맵에는 목록 만 있으면됩니다. 첫 번째 답변을 편집하는 것이 예의 바른 지 확실하지 않았습니다. 결국 나는 첫 번째 시도에서 실수를했다.
Tobias Würfl 2016 년

-2

이 DP 방법을 사용하십시오 ( /programming/4487438/maximum-sum-of-non-consecutive-elements?rq=1 ) :

배열 A [0..n]이 주어지면 인덱스 0..i를 갖는 요소를 사용하여 M (i)을 최적의 솔루션으로 만드십시오. 그런 다음 M (-1) = 0 (반복에 사용됨), M (0) = A [0] 및 M (i) = max (M (i-1), M (i-2) + A [i ])에 대해 i = 1, ..., n입니다. M (n)은 우리가 원하는 솔루션입니다. 이것은 O (n) 입니다. 다른 배열을 사용하여 각 하위 문제에 대해 선택한 항목을 저장할 수 있으므로 선택한 실제 요소를 복구 할 수 있습니다.

재귀를 M (i) = max (M (i-1), M (i-2) + A [i])로 변경하여 N으로 나눌 수있는 경우에만 저장합니다.


2
작동하지 않습니다. 이유를 알아 드리겠습니다. (힌트 : 상수 1 배열에서 실행 해보십시오.) 또한이 문제에서는 연속 요소를 허용합니다.
Yuval Filmus

1
이것은 완전히 다른 (그리고 훨씬 쉬운) 문제에 대한 아주 좋은 해결책입니다.
Evil
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.