เลือกอาหารที่มีแคลอรี่มากที่สุด


9

สมมติว่าฉันกินห้ามื้อต่อวันและเนื่องจากมีเจ็ดวันในหนึ่งสัปดาห์ฉันมีสูตรอาหารเจ็ดมื้อแต่ละมื้อรวม 35 สูตร แต่ละสูตรมีแคลอรี่นับ ในแต่ละวันจะต้องมีหนึ่งสูตรต่อมื้อและแต่ละสูตรจะถูกกำหนดเป็นอาหารเฉพาะ (เช่นคุณไม่สามารถทานแพนเค้กสำหรับอาหารค่ำ) 35 สูตรทั้งหมดจะต้องอยู่ในการแก้ปัญหาดังนั้นจึงไม่สามารถทำซ้ำสูตรในระหว่างสัปดาห์

ฉันต้องการค้นหาการจัดเรียงของมื้ออาหารซึ่งจะให้จำนวนแคลอรี่ที่มากที่สุดต่อวัน - นั่นคือฉันต้องการลดความแตกต่างของแคลอรี่ทั้งหมดที่บริโภคในแต่ละวัน

นี่ไม่ใช่ปัญหาการบ้าน แต่จริงอยู่! ฉันไม่สามารถหาวิธีที่ดีกว่าการใช้กำลังอย่างดุเดือดและมีชุดค่าผสม 7! ^ 4 ซึ่งมีจำนวนมาก


3
ผมมีความรู้สึกว่านี่คือการเปลี่ยนแปลงของปัญหาการตัดหุ้นหรืออาจจะเป็นปัญหาการบรรจุผลิตภัณฑ์
Doval

เพื่อชี้แจง - คุณมี 7 สูตรสำหรับ "มื้อแรกของวัน", 7 สำหรับ "มื้อที่สอง", 7 สำหรับ "มื้อที่ 3" และอื่น ๆ ? คุณเคยกำหนดสูตร "มื้อแรก" ให้กับ "มื้อสุดท้ายของวัน" หรือไม่? (อีกวิธีหนึ่งคุณจะเสิร์ฟแพนเค้กสำหรับอาหารเย็นหรือไม่)
Dan Pichelman

แก้ไข; คุณจะไม่
dfaulken

2
สูตรอาหารทั้ง 35 สูตรมีแคลอรี่ที่แตกต่างกันอย่างมีนัยสำคัญหรือไม่? หากคุณต้องนับแคลอรี่ให้ใกล้เคียงกับ 10 หรือ 50 แคลอรี่ที่อยู่ใกล้ที่สุด, 7! ^ 4 อาจกลายเป็น 3! ^ 4 - ซึ่งคำนวณได้อย่างง่ายดายด้วยกำลังดุร้าย
Dan Pichelman

2
เพื่อนคุณกินมากเกินไปกิน 5 มื้อ / วันจะทำให้คุณอ้วน
Pieter B

คำตอบ:


1

วิธีทำให้ปัญหาของคุณเป็นทางการยิ่งขึ้น:

คุณมี 5 หมายเลข 7 รายการแต่ละหมายเลข คุณจำเป็นต้องสร้าง 7 รายการจาก 5 หมายเลขแต่ละรายการและหาวิธีแก้ปัญหาที่มีความแตกต่างน้อยที่สุดระหว่างรายการที่มีผลรวมของตัวเลขที่ใหญ่ที่สุดและรายการที่มีขนาดเล็กที่สุด

หากคุณต้องการค้นหาวิธีแก้ปัญหาที่ดีที่สุดโดยไม่มีการแก้ปัญหาด้วยตนเองฉันเชื่อว่าคุณมีทางเลือกเพียงเล็กน้อย แต่ต้องแจกแจง แต่คุณไม่จำเป็นต้องแจกแจงทั้งหมด

วิธีการแก้ปัญหาที่คุณพบเมื่อคุณลงทะเบียนเป็น "พบดีที่สุด" ลงทะเบียนประสิทธิภาพการทำงานเกี่ยวกับการวัดของคุณ (ฉันเชื่อว่ามันเป็นความแตกต่างขั้นต่ำ) จากนั้นหากสาขาโซลูชันอยู่นอกถนนอย่างชัดเจนให้หยุดระบุ Protip: วันที่ไม่ได้สร้างจะมีการนับแคลอรี่ที่ดีที่สุดซึ่งเป็นค่าเฉลี่ยของมื้ออาหารที่เหลือทั้งหมด ลองจินตนาการว่าคุณมีรายการที่ใช้[10, 2, 2, 1, 1, 0, 0]สำหรับอาหาร 5 มื้อและคุณสร้างโซลูชันที่ 10 ในแต่ละมื้อสำหรับวันที่ 1 คุณรู้ว่าวันที่เหลือจะเฉลี่ย 5 แคลอรี่ต่อวันดังนั้นความแตกต่างจะเป็นอย่างน้อย 45 ดังนั้น คุณพบวิธีแก้ปัญหาก่อนหน้านี้แล้วว่าmax - min = 10คุณไม่ต้องไปทำอะไรเพิ่มเติม คุณจะลองเมนูอื่นโดยตรงสำหรับวันที่ 1


มันไม่ใช่ปัญหาของถังขยะ ปัญหาถังขยะไม่ใช่จำนวนถังขยะที่แน่นอนและไม่ใช่จำนวนรายการต่อถังที่แน่นอน
paparazzo

ใช่คุณถูก. ไม่ถูกต้องว่า
Arthur Havlicek

0

นี่เป็นเพียงการแฮ็ค แต่คุณจะได้รับการปิด
เพียง 3 มื้อ
โดยทั่วไปคุณล้มเหลวมื้ออาหารถ้ามันทำให้สองวันใกล้กับค่าเฉลี่ย C #

วิธีที่ดีกว่าคือการส่งคืนบูลใน Flop และวนซ้ำจนกว่าจะเสร็จสมบูรณ์

Flop จะฉลาดขึ้น คุณอาจอยู่ในตำแหน่งที่ไม่ได้ปัดอาหารเช้าเพื่อทานอาหารกลางวันและอาหารเย็น อาจมีการเปลี่ยนรหัสยาก นี่เป็นเหมือนการเรียงลำดับที่ค่าฟล็อบมากกว่าเรียงลำดับ

public static void MealEven()
{
    List<Day> Days = new List<Day>();
    Random rnd = new Random();
    decimal sum = 0;
    for(int i = 0; i<7; i ++)
    {
        int b = rnd.Next(100) + 40;
        int l = rnd.Next(100) + 60;
        int d = rnd.Next(100) + 80;
        Meal br = new Meal(enumMeal.b, b);
        Meal lu = new Meal(enumMeal.l, l);
        Meal di = new Meal(enumMeal.d, d);
        Day day = new Day(br, lu, di);
        Days.Add(day);
        sum += day.Calories;
    }
    decimal avg = sum / 7;
    foreach (Day d in Days.OrderBy(x => x.Calories))
        System.Diagnostics.Debug.WriteLine(d.Calories);
    System.Diagnostics.Debug.WriteLine("");

    Day low;
    Day high;
    Day lowLast = null;
    Day highLast = null;
    int count = 0;
    while (true)
    {   // first do high and low
        low = Days.OrderBy(x => x.Calories).FirstOrDefault();
        high = Days.OrderByDescending(x => x.Calories).FirstOrDefault();
        if (lowLast != null && lowLast == low && highLast == high)
            break;
        if (count > 1000)
            break;
        lowLast = low;
        highLast = high;
        count++;               
        Flop(ref high, ref low);
    }
    foreach (Day d in Days.OrderBy(x => x.Calories))
        System.Diagnostics.Debug.WriteLine("{0} {1} {2} {3}", d.Calories, d.B.Calories, d.L.Calories, d.D.Calories);
    System.Diagnostics.Debug.WriteLine("");

    // day a one on one pass
    for (int i = 0; i < 7; i ++)
    {
        for (int j = 0; j < 7; j++)
        {
            if (i == j)
                continue;
            Day d1 = Days[i];
            Day d2 = Days[j];
            Flop(ref d1, ref d2);
        }
    }

    foreach (Day d in Days.OrderBy(x => x.Calories))
        System.Diagnostics.Debug.WriteLine("{0} {1} {2} {3}", d.Calories, d.B.Calories, d.L.Calories, d.D.Calories);
    System.Diagnostics.Debug.WriteLine("");
}
public static void Flop (ref Day high, ref Day low)
{
    if(low.Calories > high.Calories)
    {
        int hold = low.B.Calories;
        low.B.Calories = high.B.Calories;
        high.B.Calories = hold;

        hold = low.L.Calories;
        low.L.Calories = high.L.Calories;
        high.L.Calories = hold;

        hold = low.D.Calories;
        low.D.Calories = high.D.Calories;
        high.D.Calories = hold;

    }
    decimal avg = (low.Calories + high.Calories) / (decimal)2;
    int bDiff = (high.B.Calories - low.B.Calories) < 0 ? 0 : (high.B.Calories - low.B.Calories);
    int lDiff = high.L.Calories - low.L.Calories < 0 ? 0 : (high.L.Calories - low.L.Calories);
    int dDiff = high.D.Calories - low.D.Calories < 0 ? 0 : (high.D.Calories - low.D.Calories);
    // only flop is one does not go past the average  
    if (bDiff > 0 && ((low.Calories + bDiff) < avg || (high.Calories - bDiff) > avg))
    {
        int hold = low.B.Calories;
        low.B.Calories = high.B.Calories;
        high.B.Calories = hold;
    }
    if (lDiff > 0 && ((low.Calories + lDiff) < avg || (high.Calories - lDiff) > avg))
    {
        int hold = low.L.Calories;
        low.L.Calories = high.L.Calories;
        high.L.Calories = hold;
    }
    if (dDiff > 0 && ((low.Calories + dDiff) < avg || (high.Calories - dDiff) > avg))
    {
        int hold = low.D.Calories;
        low.D.Calories = high.D.Calories;
        high.D.Calories = hold;
    }
}
public enum enumMeal {b, l, d};
public class Day
{
    public Meal B { get; set; }
    public Meal L { get; set; }
    public Meal D { get; set; }
    public Decimal Calories { get { return (Decimal)(B.Calories + L.Calories + D.Calories); } }
    public Day (Meal b, Meal l, Meal d )
    {
        B = b;
        L = l;
        D = d;
    }
}
public class Meal
{
    public enumMeal Type { get; set; }
    public int  Calories { get; set; }
    public Meal (enumMeal meal, int calories)
    {
        Type = meal;
        Calories = calories;
    }
}   

1
มีวิธีใดบ้างที่คุณสามารถเพิ่มคำอธิบายหรือความคิดเห็นบางอย่างลงในโค้ดเพื่อให้ได้คำตอบว่ามีประโยชน์มากขึ้น ฉันคิดว่าฉันเข้าใจสิ่งที่เกิดขึ้นในนั้น แต่ฉันไม่แน่ใจ
Adam Wells

@AdamWells ฉันเพิ่มความเห็นสองสามข้อ คุณไม่เข้าใจอะไร
paparazzo

มันไม่ได้คลิกด้วยฟลอพ ทำให้รู้สึกตอนนี้ขอบคุณ!
Adam Wells

ฉันไม่สามารถบอกได้ว่านี่เป็นรหัส Java หรือไม่ ใช่ไหม ? ขออภัยวัน Java และ Cx ของฉันอยู่ไกลฉัน หลักอยู่ที่ไหน
Arthur Havlicek

@ArthurHavlicek รหัส C # พวกเขาดูมากเหมือนกัน
paparazzo

0

ขั้นแรกให้คำนวณจำนวนแคลอรี่เฉลี่ยต่อมื้อ จากนั้นคำนวณจำนวนเฉลี่ยของ Colorie ต่อวัน สิ่งเหล่านี้จะเป็นตัวชี้วัดที่เราสามารถวัดได้ เรียงลำดับมื้อถัดไป

ตอนนี้เพียงเลือกอาหารที่สูงที่สุดและต่ำที่สุดจากการเรียงลำดับ หากมื้ออาหารอยู่ในช่วงเวลาเดียวกันคุณจะต้องไปที่ต่ำสุดหรือสูงที่สุดถัดไปจนกว่าคุณจะพบอาหารที่ไม่ได้อยู่ในช่วงเวลานั้น (อาหารเย็น ฯลฯ ) ทำเช่นนี้สำหรับ 4 มื้อแรก (สูง / ต่ำ) ในมื้อที่ 5 เลือกอาหารที่ทำให้คุณใกล้เคียงกับค่าเฉลี่ยมากที่สุด บันทึกอาหารมื้อที่ 5 ลงในถังแยกต่างหาก ล้างและทำซ้ำ 7 ครั้ง

นี่จะเป็นชุดมื้อแรกของคุณ นี้จะสวยได้ หากคุณต้องการการกระจายที่เหมาะสมบางอย่างก็สามารถทำได้ด้วยมื้อที่ 5

ผ่านถังอาหารมื้อที่ 5 และลองเปลี่ยนมื้ออาหารมื้อที่ 5 ระหว่างวันเพื่อดูว่ามื้ออาหารยิ่งกว่าเดิมหรือไม่ คุณจะต้องใช้กฎเดียวกัน (ไม่เกินหนึ่งมื้อต่อครั้ง) หนึ่งอาจหรืออาจไม่ได้รับการตั้งค่ามากยิ่งขึ้น ใช้ค่าเฉลี่ยที่คำนวณไว้ก่อนหน้านี้เพื่อดูว่ามีการปรับปรุงหรือไม่ จะมีชุดค่าผสมที่น้อยลงมากตั้งแต่ 4 มื้อแรกได้รับการแก้ไขตามสูง / ต่ำ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.