Информация об изменениях

Сообщение Re[7]: Вариация задачи о сдаче от 17.01.2023 17:23

Изменено 17.01.2023 18:16 gandjustas

Re[7]: Вариация задачи о сдаче
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, gandjustas, Вы писали:

S>>>Пусть будут десятки чисел.
G>>Чем перебор не устраивает?
S>комбинаторикой.

Вот накидал перебором для 50 до 1000 чисел https://dotnetfiddle.net/q51ICI
С 50 числами до 1000 работает за 0.1, с числами до 1М за 0.14
Можно пооптимизировать, можно применить ДП, думаю будет еще быстрее

using System;
using System.Linq;
using System.Collections.Generic;

var rnd = new Random();

var numbers = Enumerable.Range(0, 50).Select(_ => rnd.Next(2,1000)).ToArray();
Array.Sort(numbers);

Console.WriteLine($"[{string.Join(", ",numbers)}]");
var filtered = numbers.Where(x => IsSumOf(x, numbers.TakeWhile(n => n < x).OrderDescending().ToList()));
Console.WriteLine($"Filtered [{string.Join(", ",filtered)}]");

bool IsSumOf(int x, IEnumerable<int> numbers)
{
    if (!numbers.Any()) return false;
    var h = numbers.First();
    var t = numbers.Skip(1);
    var mod = x % h;
    if (mod == 0) return true;    
    for (var i = x / h; i>= 0; i--)
    {
        if (IsSumOf(x - i * h, t)) return true;
    }
    return false;
}
Re[7]: Вариация задачи о сдаче
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, gandjustas, Вы писали:

S>>>Пусть будут десятки чисел.
G>>Чем перебор не устраивает?
S>комбинаторикой.

Вот накидал перебором для 50 до 1000 чисел https://dotnetfiddle.net/q51ICI
С 50 числами до 1000 работает за 0.1, с числами до 1М за 0.14
Можно пооптимизировать, можно применить ДП, думаю будет еще быстрее

using System;
using System.Linq;
using System.Collections.Generic;

var rnd = new Random();

var numbers = Enumerable.Range(0, 50).Select(_ => rnd.Next(2,1000)).ToArray();
Array.Sort(numbers);
Console.WriteLine($"[{string.Join(", ",numbers)}]");

var filtered = numbers.Where((x, i)  => !IsSumOf(x, numbers[0..i]));

Console.WriteLine($"Filtered [{string.Join(", ",filtered)}]");

bool IsSumOf(int x, Span<int> numbers)
{
    if (numbers.Length == 0) return false;
    var h = numbers[^1];
    var mod = x % h;
    if (mod == 0) return true;    
    for (var i = x / h; i>= 0; i--)
    {
        if (IsSumOf(x - i * h, numbers[..^1])) return true;
    }
    return false;
}