Elementów jest tyle, co komórek macierzy, tak więc każde ułożenie będzie jedną z permutacji zbionu N*M elementowego.
Najprostszy ale najgorszy byłby zwykły bruteforce, tj wygenerować każdą możliwą permutacje (jest ich (M*N)! a więc dużo) i sprawdzić, które z nich tworzą macierz posortowaną.
Znacznie lepszy byłby ulepszony bruteforce, a konkretniej rekurencyjny algorytm backtrackingu. W twoim przypadku polegałby mniej więcej na zasadzie "Wstawiaj niewykorzystane elementy do macierzy dopóki macierz jest posortowana. Jeśli porządek zostanie zaburzony wróć do momentu, kiedy można było wstawić inny, kolejny element i kontynuuj wstawianie." Dokładniejszy opis idei backtrackingu znajdziesz w internecie np. http://en.wikipedia.org/wiki/Backtracking
Z backtrackingiem dalej można kombinować ustalając jakie wartości mogą być w jakich komórkach. Można zauważyć, że:
0 musi być w pierwszej komórce macierzy (0, 0)
1 musi być za 0, czyli w komórce (1,0) (1,1) lub (0,1).
2 musi być za 0 lub 1, czyli możliwe miejsca to (1,0) (1,1) (0,1) (2,0) (2,1) (2,2) (1,2) (0, 2)
3 musi ... i dochodzimy do wniosku, że 'k' musi być w komórce (0..k, 0..k)
Od drugiej strony to samo:
mn-1 musi być w komórce (n-1, m-1)
mn-2 może być w komórkach (n-2, m-1) (n-2, m-2) (n-1, m-2)
mn-3 może być w komórkach (n-2, m-1) (n-2, m-2) (n-1, m-2) (n-3, m-1) (n-3, m-2) (n-3, m-3) (n-2, m-3) (n-1, m-3)
itd. więc 'mn-k' musi być w komórkach (n-k..n-1, m-k..m-1)
Można się więc zastanowić, z jakiego zakresu liczby mogą być w komórce (i, j). Jeśli by oznaczyć 'a=min(i,j), b=min(n-i,m-j)', to w komórce (i,j) odpadają liczby mniejsze od 'a' (bo nie wykraczają poza (0..a-1, 0..a-1)) oraz liczby większe od mn-b (bo nie wykraczają poza (n-b+1..n-1, m-b+1..m-1).
Tak więc podczas wstawiania elementów do komórki (i,j) warto wybierać tylko te z zakresu a..mn-b.