Just algorithm!
Price is Wrong



ข้อถัดมา Price is wrong

จริงๆ ข้อนี้ไม่เกี่ยวอะไรกับราคา

เค้าจะให้ตัวเลขเรามาชุดนึง ซึ่งเป็นราคาสินค้า

แล้วให้ตอบว่าต้องแก้ตัวเลขอย่างน้อยกี่ตัวจึงทำให้ตัวเลขเรียงกัน

แต่แทนที่จะตอบตัวเลข เราต้องตอบชื่อสินค้าที่ราคาผิด

อ่านเพิ่มเติม ที่นี่



ข้อนี้ก็ยังเป็น Dynamic Programming

จุดสนุกของ Dynamic Programming คือ การวิเคราะห์หา subproblem

ซึ่งบางครั้ง ต้องอาศัยการคิดนอกกรอบแบบสุดๆ



วิธีคิดของข้อนี้คือ

ให้สมมติว่ามี ตัวเลขพิเศษมาประกบหัวท้าย เช่น

20 15 40 30 60

ให้เพิ่มตัวเลขน้อยสุด กับมากสุดเข้าไป เช่น เลข 0 และ 101 เป็น

0 20 15 40 30 60 101

แล้วลองหยิบตัวเลขมาตัวนึง เช่น 40

ทีนี้เราก็ได้ subproblem คือ เรียง 0 20 15 40 กับเรียง 40 30 60 100



ดังนั้น เราจะได้สูตรว่า



minGuess (min, max) = min { minGuess(min, i) + minGuess(i, max) }



แค่นี้เองครับ ง่ายบ่



ทีนี้ ตัวเลขที่เราจะเอามาเป็น node สำหรับแยก subproblem ต้องมีค่าระหว่าง min กับ max

เรามาสร้าง operator สำหรับทำ between กัน
let inline (<.) a b =
    a, b
let inline (.<) (a, b) c =
    a < b && b < c

มี 2 operators เหตุเพราะว่า f# ไม่รองรับการทำ ternary operator

ทีนี้วิธีใช้ operator นี้คือ a <. b .< c

ดูแล้วเข้าใจง่ายฝุดๆ



มาเริ่มกันเลยครับ
let solve names prices =
    let prices = Array.concat [[|0|]; prices; [|101|]]
    let priceOf = Array.get prices
    let nameOf n = Array.get names (n-1)

names คือ array ของชื่อสินค้า

prices คือ ราคาของสินค้า และทีนี้เรามีการประกบ 0 กับ 101 เข้าไปหัวท้าย

priceOf กับ nameOf คือการดึงราคาและชื่อ โดยใส่ index เข้าไป
let rec minGuess =
    let minGuessX (min, max) =
        let inside = { min+1..max-1 } |> Seq.filter (fun i -> priceOf min <. priceOf i .< priceOf max)
        if Seq.isEmpty inside then
            let newSet = { min+1..max-1 } |> Seq.map nameOf
                                          |> Set.ofSeq
            newSet.Count, newSet
        else
            seq {
                for i in inside do
                let leftCount,leftSet = minGuess (min, i)
                let rightCount,rightSet = minGuess (i, max)
                yield leftCount+rightCount, leftSet+rightSet
            } |> Seq.min
    memoize minGuessX

บรรทัด let inside คือ ดึงเฉพาะตัวเลขที่ราคาอยู่ระหว่าง min กับ max

ถ้าไม่เจอ inside หมายความว่าต้องปรับราคาทุกตัว

แต่ถ้าเจอ ก็ใช้ inside เป็น node แล้วหา minGuess ทั้งด้านซ้ายและด้านขวา

แล้ว return ผลเฉพาะค่า minimum



สุดท้ายก็ return ผล
let _,set = minGuess (0, prices.Length - 1)
String.Join(" ", set)

จบ



Create Date : 04 มิถุนายน 2557
Last Update : 4 มิถุนายน 2557 20:45:31 น. 0 comments
Counter : 870 Pageviews.

ชื่อ :
Comment :
  *ใช้ code html ตกแต่งข้อความได้เฉพาะสมาชิก
 

chaowman
Location :
กรุงเทพฯ Thailand

[Profile ทั้งหมด]

ฝากข้อความหลังไมค์
Rss Feed
Smember
ผู้ติดตามบล็อก : 8 คน [?]





New Comments
Group Blog
 
All Blogs
 
Friends' blogs
[Add chaowman's blog to your web]
Links
 

 Pantip.com | PantipMarket.com | Pantown.com | © 2004 BlogGang.com allrights reserved.