Это вопрос с алгоритмом, у меня есть решение, но оно имеет проблемы с производительностью.
Описание вопроса
Существует n переменных и m требований. Требования представлены как (x <= y), что означает, что x-я переменная должна быть меньше или равна y-ой переменной. Назначьте неотрицательные числа, меньшие 10 для каждой переменной. Просьба рассчитать, сколько разных заданий соответствует всем требованиям. Два назначения различаются в том и только в том случае, если по меньшей мере одна переменная присваивается другому номеру в этих двух присваиваниях. Подберите ответ на 1007.
Формат ввода:
Первая строка ввода содержит два целых числа n и m. Затем следуют m строк, каждая из которых содержит 2 пространственно разделенных целых числа x и y, что означает требование (x <= y).
Формат вывода:
Выведите ответ в одной строке.
Ограничения:
0 < n < 14
0 < m < 200
0 <= x, y < п
Пример ввода:
6 7
1 3
0 1
2 4
0 4
2 5
3 4
0 2
Результат вывода:
1000
Ниже мое решение. требуется слишком много времени, чтобы получить результат при n = 13 и m = 199, но приемлемое время составляет 5 секунд.
Так может ли кто-нибудь подумать о лучшем способе оптимизировать это дальше? Спасибо.
Мое текущее решение:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication81
{
class Program
{
const int N = 10;
static List<Condition> condition = new List<Condition>();
static void Main(string[] args)
{
string[] line1 = Console.ReadLine().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
int n = int.Parse(line1[0]);
int m = int.Parse(line1[1]);
for (int i = 0; i < m; i++)
{
string[] line = Console.ReadLine().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
condition.Add(new Condition()
{
X = int.Parse(line[0]),
Y = int.Parse(line[1])
});
}
//
List<int[]> rlist = new List<int[]>();
for (int j = 0; j < N; j++)
{
int[] assignments = new int[n];
for (int i = 0; i < n; i++)
assignments[i] = -1;
assignments[0] = j;
rlist.Add(assignments);
}
for (int j = 1; j < n; j++)
{
List<int[]> rlist2 = new List<int[]>(rlist.Count*5);
for (int k = 0; k < rlist.Count; k++)
{
for (int l = 0; l < N; l++)
{
rlist[k][j] = l;
if (CanPassCondition(rlist[k]))
rlist2.Add((int[])rlist[k].Clone());
}
}
rlist = rlist2;
}
Console.Write(rlist.Count % 1007);
}
private static bool CanPassCondition(int[] p)
{
foreach (var c in condition)
{
if (p[c.X] == -1 || p[c.Y] == -1)
continue;
if (p[c.X] > p[c.Y])
return false;
}
return true;
}
}
class Condition
{
public int X;
public int Y;
public override string ToString()
{
return string.Format("x:{0}, y:{1}", X, Y);
}
}
}