2015-06-10 3 views
0

Приведена матрица AxB с целыми числами> = 0. Сумма каждого столбца матрицы не должна уменьшаться при перемещении слева направо. Кроме того, сумма B я колонка (последняя колонка) меньше или равна A.Устройства со следующими условиями:

Найти число различных матриц такого типа для данных А и В.

Я пытался решить используя рекурсию и мемоизация следующего образом-

функции решения()

IS-
ll solve(ll i,ll curlevel) 
{ 
if(dp[i][curlevel]!=-1) 
    return dp[i][curlevel]; 
if(i<0) 
    return dp[i][curlevel]=0; 
if(curlevel==B) 
    return dp[i][curlevel]=test(i,c); 
if(curlevel>B) 
    return dp[i][curlevel]=0; 
ll ans=0; 
for(ll k=i;k>=0;k--) 
{ 
    ans+= test(i,A)* solve(k, curlevel+1); 
} 
return dp[i][curlevel]=ans; 
} 

тест функции определяются следующим образом- (Это вычисляет нет путей суммы = «суммы» может происходить как сумма отдельных неотрицательных чисел = «мест»)

ll test(ll sum,ll places) 
{ 
if(mem[sum][places] != -1) 
    return mem[sum][places]; 
if(sum==0) 
    return mem[sum][places]=1; 
if(places==0) 
    return mem[sum][places]=0; 
ll val=0; 
for(ll i=0;i<=sum;i++) 
{ 
    val+=test(sum-i,places-1); 
} 
return mem[sum][places]=val; 
} 

Этот метод, однако, слишком медленный.

Есть ли более быстрый способ сделать это (может быть, лучше комбинаторику подхода)

+0

Этот вопрос не имеет смысла.Если A = 10 (есть 10 строк), как вы можете иметь столбец, содержащий только неотрицательные числа, сумма которых равна 10 или меньше, если только каждое значение столбца равно 1? –

+0

@ tylerdurden- 0 также можно использовать. Мы можем, например, иметь столбец с 1 '10' и остальные нули. – LTim

+3

Я подозреваю, что это связано с конкурсом http://www.codechef.com/JUNE15/problems/STDYTAB –

ответ

0

Вы предвычислять Перегородки массива - число разбиений множества А в неотрицательные части (включая нули) и порядок учета заказов (т.е. подсчет как 0 0 1, так и 0 1 0 и т. д.).

Редактировать: Partitions(k) = C(A + k - 1, A - 1)
Пример A = 4
Partitions[4] = C(7,3)=7!/(4!3!)=35
весь массив: Partitions = {1,4,10,20,35}
Для расчета разделов, использование таблицы - вращают треугольника Паскаля

1 1 1 1 1 
1 2 3 4 5 //sum of 1st row upto ith element 
1 3 6 10 15 //sum of 2st row 
1 4 10 20 35 //sum of upper row 

для A = 1000 вам нужно около 1000 * sizeof (int64) памяти (одна или две строки) и около 10^6 по модулю дополнений. Если вам нужно сделать расчеты для многих значений А, просто хранить всю таблицу (8 Мб)

Затем используйте эту формулу: // исправлен

S(columns, minsum) = Partitions[k] * Sum[k=minsum..A]{ S(columns - 1, k) } 
S(1,k) = Partitions[k] 
Result = Sum[k=0..A] { S[B,k] } 
+0

Как эффективно вычислить массив разделов? Также для каждого значения A & B потребуется предварительная калькуляция, верно? – LTim

+0

Предварительная накачка необходима для каждого A, но не зависит от B. Нет необходимости вычислять ее очень эффективно, достаточно простой рекурсии. – MBo

+0

Предварительное вычисление разделов по-прежнему очень медленное для A, B = 1000. Я использую раздел рекурсии (n, k) = partition (n-1, k) + partition (n, k-1) с memoization. – LTim

0

Начиная с последней ячейки последнего столбца , если эта ячейка имеет значение A, то все остальные ячейки в последнем столбце должны быть равны 0, поэтому в этом случае последний столбец имеет 1 возможную компоновку.

Если последняя ячейка имеет значение A-1, то ячейка рядом с ней в одном столбце может быть 0 или 1, поэтому существует одна компоновка, в которой последний столбец суммируется с A-1 и A-1 механизмы, в которых столбец суммы к А.

в общем, рекурсивной функции:

NumberOfArrangementsOfColumn(cells_remaining, value_remaining){ 
    if(value_remaining == 0) return 1; 
    if(cells_remaining == 1) return value_remaining + 1; 
    int total = 0; 
    for(int sub_value = 1; sub_value <= value_remaining; sub_value++){ 
     total += 
      NumberOfArrangementsOfColumn(cells_remaining - 1, sub_value); 
    } 
    return total; 
} 

Эта функция будет определять количество механизмов для последнего столбца. Затем вам необходимо создать еще одну рекурсивную функцию для вычисления каждого из оставшихся столбцов, начиная со следующего до последнего столбца и т. Д. Для каждого возможного значения.

Смежные вопросы