x = {3, 1}
y = {2, 5}
a Defer[x] + b Defer[y] /. First@Solve[a x + b y == {7, 11}, {a, b}]
(* x + 2 y *)
Note that the output is usable as such: evaluate it and you'll get the combination result.
If only integer coefficients are desired, changing the Solve to something like:
Solve[a x + b y == {7, 11} && {a, b} \[Element] Integers, {a, b}]
will accomplish this. If you extend things where no solutions, or multiple solutions are possible, probably want to do the Solve first, check it, then do the replace.
Edit: Here's a sketch (meaning not heavily tested, surely more elegant ways to do same) of how you might generalize this into a function:
ClearAll[combo];
SetAttributes[combo, HoldAll]l
combo[a_, b_, c_] :=
Block[{d = Defer /@ Unevaluated[{a, b}], syms = Table[Unique[], {2}]},
Total[syms*d] /. First@Solve[Total[{a, b}*(syms)] == c, syms]];
(* cobble up an example *)
m1 = {{1, 2}, {3, 4}};
m2 = {{3, 5}, {7, 9}};
(* do some combo *)
result = 3 m1 - 2 m2
(* solve and output as desired *)
combo[m1, m2, result]
(* 3 m1 - 2 m2 *)
As above, the result can be used/evaluated. If you go the generalized function route, you probably do want to check for no-solution cases, add desired limitation(s) to solve (e.g. integer only), and perhaps extend it to more than two + result arguments...