ну раз память, значит выделяете не NxM ячеек (или непрерывный блок, или N блоков по M, или M блоков по N), а (т.к. треугольная) NxN/2 + поправка. доступ реализуете уже с некоторым логическим выражением.
т.е. от индекса (i,j) адрес смещения будет зависеть сложнее. если верхняя треугольная - значит возвращать 0 для всего что ниже главной диагонали, если нижняя - что выше главной диагонали.
нет на этот счёт науки. каждый ловчит как хочет и под конкретную задачу.
ПИшникам на следующий год пригодится в любом случае). Опишу метод пар в двух словах, заодно. Там вектор из пар, строки отделяются служебной парой (-1 i), пары со значениями имеют вид (j x), где x значение.