यह समस्या दी गई श्रेणी में समारोह f(x)=n%x
की अधिकतम पाने के लिए बराबर है।चलो देखते हैं कि यह कैसे समारोह की तरह दिखता है:
यह हम अधिकतम जल्दी ही मिल सकता है कि अगर हम x=k
के साथ शुरू और फिर x
कमी है, जबकि यह कोई मतलब (x=max+1
तक) बनाता है स्पष्ट है। इसके अलावा यह चित्र दिखाता है कि x
sqrt(n)
से बड़ा है, हमें अनुक्रमिक रूप से x
को कम करने की आवश्यकता नहीं है। इसके बजाय हम तुरंत स्थानीय अधिकतम से पहले कूद सकते हैं।
int maxmod(const int n, int k)
{
int max = 0;
while (k > max + 1 && k > 4.0 * std::sqrt(n))
{
max = std::max(max, n % k);
k = std::min(k - 1, 1 + n/(1 + n/k));
}
for (; k > max + 1; --k)
max = std::max(max, n % k);
return max;
}
जादू निरंतर 4.0
पहले (महंगा) पाश की पुनरावृत्तियों की संख्या को कम करके प्रदर्शन में सुधार करने की अनुमति देता है।
सबसे खराब मामला जटिलता का अनुमान लगाया जा सकता है ओ (न्यूनतम, के, वर्ग (एन)))। लेकिन काफी बड़े k
के लिए यह अनुमान शायद निराशावादी है: हम अधिकतम तेज़ी से पा सकते हैं, और यदि k
sqrt(n)
से काफी अधिक है तो हमें इसे खोजने के लिए केवल 1 या 2 पुनरावृत्तियों की आवश्यकता है।
मैं निर्धारित करने के लिए कितने पुनरावृत्तियों n
के विभिन्न मूल्यों के लिए सबसे खराब स्थिति में जरूरत है कुछ परीक्षण किया:
n max.iterations (both/loop1/loop2)
10^1..10^2 11 2 11
10^2..10^3 20 3 20
10^3..10^4 42 5 42
10^4..10^5 94 11 94
10^5..10^6 196 23 196
up to 10^7 379 43 379
up to 10^8 722 83 722
up to 10^9 1269 157 1269
वृद्धि दर काफ़ी ओ (sqrt (एन)) से बेहतर है।
स्रोत
2015-10-13 14:09:42
"के" के उच्च मूल्यों से शुरू करके खोज को शॉर्ट सर्किट करने का एक तरीका हो सकता है। मुझे नहीं लगता कि इससे बड़े-बड़े प्रभावित होंगे। –
यह सवाल http://math.stackexchange.com/ IMO के लिए अधिक उपयुक्त है। हाथ में मुख्य समस्या प्रोग्रामेटिक की बजाय एल्गोरिदमिक है। –
@barakmanos। । । यह कहना मुश्किल है। ओपी जानता है कि समस्या को कैसे हल किया जाए, लेकिन एक कुशल कार्यान्वयन की तलाश में है। –