برنامه نویسی

مشکل برنامه نویسی آموزش نینجا – جامعه dev

بیانیه مشکل

نینجا در حال برنامه ریزی این برنامه آموزشی روزها است. او هر روز می تواند هر یک از این سه فعالیت را انجام دهد. (دویدن ، مبارزه با تمرین یا یادگیری حرکات جدید). هر فعالیت در هر روز دارای برخی از نقاط شایستگی است. از آنجا که نینجا باید تمام مهارت های خود را بهبود بخشد ، او نمی تواند در دو روز متوالی همان فعالیت را انجام دهد. آیا می توانید به نینجا کمک کنید تا حداکثر نکات شایستگی نینجا را بدست آورید؟

به شما یک آرایه 2D از نقاط اندازه n*3 “با امتیازهای مربوط به هر روز و فعالیت داده می شود. وظیفه شما محاسبه حداکثر تعداد نقاط شایستگی است که نینجا می تواند کسب کند.

به عنوان مثال
اگر آرایه “امتیاز” داده شده باشد [[1,2,5]با [3 ,1 ,1] با[3,3,3] ]، پاسخ 11 به عنوان 5 + 3 + 3 خواهد بود.
توضیح دقیق (قالب ورودی/خروجی ، یادداشت ها ، تصاویر)

محدودیت ها:

1 <= t <= 10
1 <= n <= 100000.
1 <= مقادیر آرایه های نقاط <= 100.

محدودیت زمانی: 1 ثانیه

موارد آزمایشی

ورودی نمونه 1:

2
3
1 2 5
3 1 1
3 3 3
3
10 40 70
20 50 80
30 60 90

نمونه خروجی 1:

11
210

توضیح ورودی نمونه 1:

برای اولین مورد آزمون ،
یکی از پاسخ ها می تواند این باشد:
در روز اول ، نینجا حرکات جدیدی را یاد خواهد گرفت و 5 امتیاز شایستگی کسب می کند.
در روز دوم ، نینجا در حال اجرا خواهد بود و 3 امتیاز شایستگی کسب می کند.
در روز سوم ، نینجا جنگ خواهد کرد و 3 امتیاز شایستگی کسب می کند.
کل نقطه شایستگی 11 است که حداکثر است.
از این رو ، پاسخ 11 است.

برای مورد آزمون دوم:
یکی از پاسخ ها می تواند این باشد:
در روز اول ، نینجا حرکات جدیدی را یاد خواهد گرفت و 70 امتیاز شایستگی کسب می کند.
در روز دوم ، نینجا جنگ خواهد کرد و 50 امتیاز شایستگی کسب می کند.
در روز سوم ، نینجا حرکات جدیدی را یاد خواهد گرفت و 90 امتیاز شایستگی کسب می کند.
کل نقطه شایستگی 210 است که حداکثر است.
از این رو ، پاسخ 210 است.

ورودی نمونه 2:

2
3
18 11 19
4 13 7
1 8 13
2
10 50 1
5 100 11

نمونه خروجی 2:

45
110

رویکرد

فرض کنید اگر مثال را در نظر بگیریم:

| 10 50 1
| 5 100 11

و سعی کنید مشکل را با حریم حل کنید. ما از ردیف اول 50 امتیاز و 11 امتیاز از ردیف دوم کسب می کنیم. چرا 11؟ به وضوح بیان شده است که ما نمی توانیم در دو روز متوالی همان فعالیت را انجام دهیم. از این رو ، یک فعالیت 100 امتیازی قابل تکرار نیست.
اما این امتیاز ما را افزایش نمی دهد.

اکنون ، گزینه بعدی که ما داریم این است که همه امکانات را امتحان کنیم. بنابراین ، بازگشت راهی است که باید انجام شود.
ما می توانیم مشکل را به عنوان تابعی که دو پارامتر را می پذیرد ، نشان دهیم.

  1. فهرست
  2. فعالیت قبلی انجام شده است.

بگذارید موارد زیر را در نظر بگیریم:

-> 0 یعنی ما فعالیت 0 را انجام داده ایم
-> 1 به این معنی است که ما یک فعالیت جنگی انجام داده ایم
-> 2 یعنی ما فعالیت یادگیری را انجام داده ایم
-> 3 یعنی ما تاکنون هیچ فعالیتی انجام نداده ایم.

ما می توانیم از آخرین شاخص شروع کنیم و در آن زمان ، هنوز هیچ فعالیتی انجام نداده ایم. بنابراین می توانیم هر سه فرصت فعالیت را امتحان کنیم و به بالا برویم.

پس از رسیدن به مورد پایه ، یعنی ، index = 0 ، می توانیم کار را انجام دهیم و فقط وظیفه ای را که قبلاً انجام نشده است در نظر بگیریم. حداکثر را هر بار پیگیری کنید.

function(index, task) {
  if index = 0:
     go through the task
     track max
  return max;

  for all other index cases
     go through the task
     track the max by recursively going up through all possibilities
  return max at the end
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

زیرنویس های همپوشانی وجود خواهد داشت ، و ما می توانیم با یک آرایه 2D DP ، DP ، یادآوری را انجام دهیم[index][task]، که می گوید نکاتی را که ما جمع آوری کرده ایم تا فهرست را که وظیفه انجام شده است انجام دهیم.

پیچیدگی زمان:

بازگشت

  • پیچیدگی زمان نمایی و پیچیدگی فضایی O (N)

  • O (n * 4 * 3) پیچیدگی زمان و O (n * 4) + O (n) پیچیدگی فضایی برای بازگشت + به یاد ماندنی.

  • O (n * 4 * 3) پیچیدگی زمان و O (n * 4) پیچیدگی فضایی برای روش جدول بندی.

  • O (n * 4 * 3) پیچیدگی زمان و O (4) پیچیدگی فضایی برای نسخه جدول بندی بهینه سازی شده فضا.

رمز

بازگشت

import java.util.*;
public class Solution {
    public static int ninjaTraining(int n, int points[][]) {
        if (points == null || n == 0) {
            return 0;
        }
        // 0 means we have performed 0th activity running
        // 1 means we have performed fighting activity
        // 2 means we have performed learning activity
        // 3 means we haven't done any activity till now.
        return findMaxPoints(points, n - 1, 3);
    }

    private static int findMaxPoints(int [][] points, int index, int previousActivity) {
        if (index == 0) {
            int maxPoints = 0;
            int currentPoint = 0;
            for (int task = 0; task < 3; task++) {
                if (task != previousActivity) {
                    maxPoints = Math.max(maxPoints, points[0][task]);
                }
            }
            return maxPoints;
        }
        int maxPoints = 0;
        for (int task = 0; task < 3; task++) {
            if (task != previousActivity) {
                int pointsEarned = points[index][task] + findMaxPoints(points, index - 1, task);
                maxPoints = Math.max(maxPoints, pointsEarned);
            }
        }
        return maxPoints;
    }

}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

یادبود

import java.util.*;
public class Solution {
    public static int ninjaTraining(int n, int points[][]) {
        if (points == null || n == 0) {
            return 0;
        }
        // 0 means we have performed 0th activity running
        // 1 means we have performed fighting activity
        // 2 means we have performed learning activity
        // 3 means we haven't done any activity till now.
        int [][] dp = new int [n][4];
        for (int [] d : dp) {
            Arrays.fill(d, -1);
        }
        return findMaxPoints(points, n - 1, 3, dp);
    }

    private static int findMaxPoints(int [][] points, int index, int previousActivity, int [][] dp) {
        if (index == 0) {
            int maxPoints = 0;
            int currentPoint = 0;
            for (int task = 0; task < 3; task++) {
                if (task != previousActivity) {
                    maxPoints = Math.max(maxPoints, points[0][task]);
                }
            }
            return maxPoints;
        }
        if (dp[index][previousActivity] != -1) {
            return dp[index][previousActivity];
        }
        int maxPoints = 0;
        for (int task = 0; task < 3; task++) {
            if (task != previousActivity) {
                int pointsEarned = points[index][task] + findMaxPoints(points, index - 1, task, dp);
                maxPoints = Math.max(maxPoints, pointsEarned);
            }
        }
        return dp[index][previousActivity] = maxPoints;
    }

}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

جدول بندی

import java.util.*;
public class Solution {
    public static int ninjaTraining(int n, int points[][]) {
        if (points == null || n == 0) {
            return 0;
        }
        // 0 means we have performed 0th activity running
        // 1 means we have performed fighting activity
        // 2 means we have performed learning activity
        // 3 means we haven't done any activity till now.
        int [][] dp = new int [n][4];
        for (int [] d : dp) {
            Arrays.fill(d, -1);
        }
        dp[0][0] = Math.max(points[0][1], points[0][2]);
        dp[0][1] = Math.max(points[0][0], points[0][2]);
        dp[0][2] = Math.max(points[0][0], points[0][1]);
        dp[0][3] = Math.max(points[0][0], Math.max(points[0][1], points[0][2]));
        for (int index = 1; index < n; index++) {
            for (int last = 0; last < 4; last++) {
                int maximumPoint = 0;
                for (int task = 0; task < 3; task++) {
                    if (last != task) {
                        int pointsEarned = points[index][task] + dp[index - 1][task];
                        maximumPoint = Math.max(pointsEarned, maximumPoint);
                    }

                }
                dp[index][last] = maximumPoint;
            }
        }
        return dp[n - 1][3];
    }
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

بهینه سازی فضا

ایده اصلی بهینه سازی این است که ما فقط به جزئیات ردیف قبلی برای محاسبه ردیف فعلی نیاز داریم. بنابراین ، ذخیره آرایه DP با اندازه N * 4 لازم نیست. در عوض ، فقط یک آرایه DP با اندازه 4 کافی است که نتیجه ردیف قبلی را ذخیره می کند.

import java.util.*;
public class Solution {
    public static int ninjaTraining(int n, int points[][]) {
        if (points == null || n == 0) {
            return 0;
        }
        // 0 means we have performed 0th activity running
        // 1 means we have performed fighting activity
        // 2 means we have performed learning activity
        // 3 means we haven't done any activity till now.
        int [][] dp = new int [n][4];
        for (int [] d : dp) {
            Arrays.fill(d, -1);
        }
        int [] previous = new int [4];
        int [] current = new int [4];
        previous[0] = Math.max(points[0][1], points[0][2]);
        previous[1] = Math.max(points[0][0], points[0][2]);
        previous[2] = Math.max(points[0][0], points[0][1]);
        previous[3] = Math.max(points[0][0], Math.max(points[0][1], points[0][2]));
        for (int index = 1; index < n; index++) {
            for (int last = 0; last < 4; last++) {
                int maximumPoint = 0;
                for (int task = 0; task < 3; task++) {
                    if (last != task) {
                        int pointsEarned = points[index][task] + previous[task];
                        maximumPoint = Math.max(pointsEarned, maximumPoint);
                    }

                }
                current[last] = maximumPoint;
            }
            int [] temp = previous;
            previous = current;
            current = temp;
        }
        return previous[3];
    }
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا