I've always found cursors a really slow way of doing pretty much anything in SQL, to say nothing of being a horror to code if it's big enough.
There could be a fourth way. Create a temporary table containing the name and object_id values of every user table in the database. Then create a loop to do the following:
a. Select the name of the table object with the lowest object_id value;
b. Execute a string of dynamic SQL to count the number of rows in the table bearing the name that you retrieved in step 1;
c. Delete the record in the temporary table that you've just been looking at;
d. Repeat until the temporary table is empty;
You could refine it further by writing the result of the count into a new table (temporary or otherwise). Or even by adding an additional column to the original temporary table and then updating that each time. The only difference is that you wouldn't delete the record once you'd finished with it, merely select the minimum object_id value as long as it was higher than the object_id value you'd just finished with.
Just a thought :-)