Another thing to consider is nested master pages. I have a similar design layout I'm doing in a current project, and we have a "base" master page that does all of our script includes, header and footer, and has just a single ContentPlaceHolder that represents everything between the header and footer. We then have a nested master page that uses the base master page, but adds a right "aside" column. For pages where we want the right column visible, we use the nested master page. For pages where we don't want it rendered, we use the base master page.
A strategy like this would definitely prevent your column #3 from being rendered at all (as opposed to being rendered and just being empty, which might not achieve the layout you're going for).
It looks something like this:
Base master page:
<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="MasterBase.Master.cs" Inherits="MasterBase" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
...
<asp:ContentPlaceHolder ID="head" runat="server" />
</head>
<body>
<form id="form1" runat="server">
<!-- HEADER -->
...
<!-- CONTENT -->
<asp:ContentPlaceHolder ID="bodyContent" runat="server" />
<!-- FOOTER -->
...
</form>
</body>
</html>
Nested Master Page
<%@ Master Language="C#" MasterPageFile="~/MasterBase.Master" AutoEventWireup="true" CodeBehind="MasterWithColumns.master.cs" Inherits="MasterWithColumns" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
<asp:ContentPlaceHolder ID="head" runat="server" />
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="bodyContent" runat="server">
<!-- CENTER COLUMN -->
<div id="centerCol">
<asp:ContentPlaceHolder ID="bodyContent" runat="server" />
</div>
<!-- RIGHT COLUMN -->
<div id="rightCol">
<asp:ContentPlaceHolder ID="rightColumn" runat="server" />
</div>
</asp:Content>