Line of sight calculations don't have to be expensive. In fact, you can nail them down to a range check and a common-bits check on a 64-bit bitmap. I blogged about this technique recently.
http://dillingers.com/blog/2014/05/29/roguelike-ai-8/It's basically a way to do the field-of-view calculation at dungeon generation, and cache the result as one 64-bit bitmask per square. It makes map generation take a second or so longer depending on your CPU (well, and on the map itself; some are harder than others).
As I initially developed it, it was a fast, approximate field of view suitable for monsters - It could be wrong sometimes. But the current algorithm makes false positives impossible and allows you to mark the few imperfect squares where you might get a false negative.
So in the one-out-of-ten-thousand or so cases where both the viewer and the thing it's trying to view are in imperfect squares, you can do the quick check (because if it says LOS exists it's always right because of "no false positives") and if it fails you might have a "false negative" in that case so you can do a conventional line-of-sight check if you need perfection.
You do have to recalculate your bitmasks when someone digs opening new line-of-sight. But that's rare enough that it doesn't cause much problem.
Pathfinding isn't particularly expensive either; Most pathfinding is chase and follow behavior centered on the player character, and sight gradient pathfinding is very good for that case and works in constant time. Another recent blog article:
http://dillingers.com/blog/2014/05/16/roguelike-ai-6/Because you have to traverse the map anyway, each turn as the player character calculates FOV and track which squares are in view, you can get sight gradient pathfinding essentially for free: Track which squares are in view by writing a number into them (a number calculated from current turn and distance from player). Thereafter, any monster standing on a square the player has ever seen can pathfind to the player simply by stepping into the neighboring square with the highest available sight gradient number. It works so well for chase-and-follow that you have to limit it to avoid being grossly unfair.
Doing more general pathfinding with A* or Dijkstra's algorithm is relatively expensive, but it doesn't have to be expensive per monster: You can share the cost of pathfinding across all monsters that have the same goal point (or set of goal points) and movement costs by having them use a common pathfinding-cost map, and calculate based on navigation costs from the (shared) goal points to the (individual) origin points instead of the more usual origin-to-goal direction. Another blog post, covering this technique in the context of escape and avoidance....
http://dillingers.com/blog/2014/06/15/roguelike-ai-9/That way when ant 234, which is pathfinding to one of the same set of goal points as ant 221, considers a square whose navigation costs were already calculated back when ant 221 was pathfinding, those navigation costs already cached are valid for ant 234 as well. In the reductio ad absurdum case, ant 234 may even be standing on a square whose navigation costs were already calculated for ant 221, so ant 234 gets its navigation entirely for free.
Finally, there are good cheap ways to reduce navigation costs even more. First of all you can use a navigation table (hmm, I guess that's a Roguelike AI article I still need to write) to handle longer-range navigation. Each entry in a navigation table is a map segment within which navigation is essentially trivial - a room, or a straight-ish chunk of cave or corridor. Special squares called 'waypoints' are in both of two (or maybe even more than 2) segments. And part of map generation is to 'parse' the map into segments and build a navigation table.
Then you can define a 'magic navigator'' function where you tell it "I'm at square X Y and I want to get to square P Q, which way should I go?" and it just tells you in constant time. The way it works in the background is, "Square X Y is (lookup) in segment 9, Square P Q is (lookup) in segment 22, the best way to get from segment 9 to section 22 means first moving to (lookup) segment 11, and to get to segment 11 from segment 9, you go (lookup) to square M N which is the waypoint between 9 and 11. And square M N is (simple math) NorthEast of square X Y. "
Will the navigation table always find the best solution? If you get fiddly and deal with a lot of corner cases and movement-cost lookups and end-segment navigation cost calculations you can make it find the best solution. But that's hard. It's flatly easy to make it find a damn good one and find it fast.