У меня есть код:
public List<VideoInfo> FillWithTheMostVideos(string folderPath, double eventStart, double eventLength, List<VideoInfo> VideosOnTimeline)
{
    List<VideoInfo> videoInfos = folderAnalizator.GetVideoInfoFromFolder(folderPath)
        .Except(VideosOnTimeline, new VideoInfoNameComparer())
        .ToList();

    videoInfos = videoInfos.OrderByDescending(v => v.DurationInMilliseconds).ToList();

    Dictionary<double, List<VideoInfo>> dp = new Dictionary<double, List<VideoInfo>> { { 0, new List<VideoInfo>() } };

    foreach (var video in videoInfos)
    {
        var newDp = new Dictionary<double, List<VideoInfo>>(dp);

        foreach (var entry in dp)
        {
            double newDuration = entry.Key + video.DurationInMilliseconds;

            if (newDuration <= eventLength && !newDp.ContainsKey(newDuration))
            {
                var newList = new List<VideoInfo>(entry.Value) { video };

                int generalVideo = video.GeneralVideo;
                double totalGeneralDuration = newList.Where(v => v.GeneralVideo == generalVideo).Sum(v => v.DurationInMilliseconds);

                bool allCopyrightFree = newList.All(v => v.CopyrightFree);

                if (totalGeneralDuration <= 19000 || allCopyrightFree)
                {
                    newDp[newDuration] = newList;
                }
            }
        }

        dp = newDp;
    }

    var bestMatch = dp.OrderByDescending(x => x.Key).FirstOrDefault().Value;

    if (bestMatch == null || bestMatch.Count == 0 || bestMatch.Count == 1)
    {
        bestMatch = FindNearestVideosByDuration(videoInfos, eventStart, eventLength, VideosOnTimeline);
        return bestMatch ?? new List<VideoInfo>();
    }
    else
    {
        bestMatch = bestMatch.OrderBy(v => v.VideoSegment).ToList();

        double currentStart = eventStart;
        foreach (var video in bestMatch)
        {
            video.StartOnTimeline = currentStart;
            video.LengthOnTimeline = video.DurationInMilliseconds;
            video.EndOnTimeline = currentStart + video.LengthOnTimeline;
            VideosOnTimeline.Add(video);
            currentStart = video.EndOnTimeline;
        }

        // Проверяем, осталась ли не заполненная часть отрезка
        double remainingDuration = eventLength - bestMatch.Sum(v => v.DurationInMilliseconds);
        if (remainingDuration > 0)
        {
            // Ищем видео для оставшейся части отрезка
            var remainingVideos = FindNearestVideosByDuration(videoInfos, currentStart, remainingDuration, VideosOnTimeline);
            if (remainingVideos != null && remainingVideos.Count > 0)
            {
                bestMatch.AddRange(remainingVideos);
            }
        }

        return bestMatch ?? new List<VideoInfo>();
    }
}

Смотри, я попробовал функцию на конкретном примере:
eventStart = 0, eventLength = 23540.
VideosOnTimeline: Пусто.
Видео в папке:
Видео А: GeneralVideo = 1, DurationInMilliseconds = 7000.
Видео Б: GeneralVideo = 2, DurationInMilliseconds = 12000.
Видео В: GeneralVideo = 3, DurationInMilliseconds = 3000.
Видео Г: GeneralVideo = 4, DurationInMilliseconds = 4000.

После выполнения на таймлайне появилось 4 видео: с полной длительностью видео А, Б, В, и с длительностью 1540 мс Видео Г.
Можно ли сделать так, чтобы если функция понимала, что если длина оставшейся незаполненной части отрезка может быть заполнена растягиванием одного или нескольких уже выбранных видео не более чем на 15%, то вместо поиска дополнительных видео, она будет проводить эти вычисления. При этом должна сохраниться проверка общей длительности в 19000 мс для  видео с одинаковыми GeneralVideo.