﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-bluesea147-文章分类-ACM</title><link>http://www.cppblog.com/bluesea147/category/14478.html</link><description /><language>zh-cn</language><lastBuildDate>Wed, 11 Aug 2010 13:30:34 GMT</lastBuildDate><pubDate>Wed, 11 Aug 2010 13:30:34 GMT</pubDate><ttl>60</ttl><item><title>二分法浅谈 (2)</title><link>http://www.cppblog.com/bluesea147/articles/122780.html</link><dc:creator>蓝色的大海</dc:creator><author>蓝色的大海</author><pubDate>Mon, 09 Aug 2010 07:01:00 GMT</pubDate><guid>http://www.cppblog.com/bluesea147/articles/122780.html</guid><wfw:comment>http://www.cppblog.com/bluesea147/comments/122780.html</wfw:comment><comments>http://www.cppblog.com/bluesea147/articles/122780.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/bluesea147/comments/commentRss/122780.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/bluesea147/services/trackbacks/122780.html</trackback:ping><description><![CDATA[<meta http-equiv="Content-Type" content="text/html; charset="utf-8"">
<meta name="ProgId" content="Word.Document">
<meta name="Generator" content="Microsoft Word 12">
<meta name="Originator" content="Microsoft Word 12">
<link rel="File-List" href="file:///C:%5CUsers%5CHUJIAN%7E1%5CAppData%5CLocal%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_filelist.xml">
<link rel="Edit-Time-Data" href="file:///C:%5CUsers%5CHUJIAN%7E1%5CAppData%5CLocal%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_editdata.mso">
<link rel="OLE-Object-Data" href="file:///C:%5CUsers%5CHUJIAN%7E1%5CAppData%5CLocal%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_oledata.mso"><!--[if !mso]>
<style>
v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
</style>
<![endif]-->
<link rel="themeData" href="file:///C:%5CUsers%5CHUJIAN%7E1%5CAppData%5CLocal%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_themedata.thmx">
<link rel="colorSchemeMapping" href="file:///C:%5CUsers%5CHUJIAN%7E1%5CAppData%5CLocal%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_colorschememapping.xml"><!--[if gte mso 9]><xml>
Normal
0
7.8 磅
0
2
false
false
false
EN-US
ZH-CN
X-NONE
MicrosoftInternetExplorer4
</xml><![endif]--><!--[if gte mso 9]><xml>
</xml><![endif]--><style>
<!--
/* Font Definitions */
@font-face
{font-family:宋体;
panose-1:2 1 6 0 3 1 1 1 1 1;
mso-font-alt:SimSun;
mso-font-charset:134;
mso-generic-font-family:auto;
mso-font-pitch:variable;
mso-font-signature:3 680460288 22 0 262145 0;}
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;
mso-font-charset:0;
mso-generic-font-family:roman;
mso-font-pitch:variable;
mso-font-signature:-1610611985 1107304683 0 0 415 0;}
@font-face
{font-family:华文新魏;
panose-1:2 1 8 0 4 1 1 1 1 1;
mso-font-charset:134;
mso-generic-font-family:auto;
mso-font-pitch:variable;
mso-font-signature:1 135200768 16 0 262144 0;}
@font-face
{font-family:"\@宋体";
panose-1:2 1 6 0 3 1 1 1 1 1;
mso-font-charset:134;
mso-generic-font-family:auto;
mso-font-pitch:variable;
mso-font-signature:3 680460288 22 0 262145 0;}
@font-face
{font-family:"\@华文新魏";
panose-1:2 1 8 0 4 1 1 1 1 1;
mso-font-charset:134;
mso-generic-font-family:auto;
mso-font-pitch:variable;
mso-font-signature:1 135200768 16 0 262144 0;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{mso-style-unhide:no;
mso-style-qformat:yes;
mso-style-parent:"";
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
mso-pagination:none;
font-size:10.5pt;
mso-bidi-font-size:10.0pt;
font-family:"Times New Roman","serif";
mso-fareast-font-family:宋体;
mso-font-kerning:1.0pt;}
p.MsoFootnoteText, li.MsoFootnoteText, div.MsoFootnoteText
{mso-style-unhide:no;
mso-style-link:"脚注文本 Char";
margin:0cm;
margin-bottom:.0001pt;
mso-pagination:none;
layout-grid-mode:char;
font-size:9.0pt;
mso-bidi-font-size:10.0pt;
font-family:"Times New Roman","serif";
mso-fareast-font-family:宋体;
mso-font-kerning:1.0pt;}
span.MsoFootnoteReference
{mso-style-unhide:no;
vertical-align:super;}
span.Char
{mso-style-name:"脚注文本 Char";
mso-style-unhide:no;
mso-style-locked:yes;
mso-style-link:脚注文本;
mso-ansi-font-size:9.0pt;
font-family:"Times New Roman","serif";
mso-ascii-font-family:"Times New Roman";
mso-hansi-font-family:"Times New Roman";
mso-font-kerning:1.0pt;}
.MsoChpDefault
{mso-style-type:export-only;
mso-default-props:yes;
font-size:10.0pt;
mso-ansi-font-size:10.0pt;
mso-bidi-font-size:10.0pt;
mso-ascii-font-family:Calibri;
mso-fareast-font-family:宋体;
mso-hansi-font-family:Calibri;
mso-font-kerning:0pt;}
/* Page Definitions */
@page
{mso-page-border-surround-header:no;
mso-page-border-surround-footer:no;
mso-footnote-separator:url("file:///C:/Users/HUJIAN~1/AppData/Local/Temp/msohtmlclip1/01/clip_header.htm") fs;
mso-footnote-continuation-separator:url("file:///C:/Users/HUJIAN~1/AppData/Local/Temp/msohtmlclip1/01/clip_header.htm") fcs;
mso-endnote-separator:url("file:///C:/Users/HUJIAN~1/AppData/Local/Temp/msohtmlclip1/01/clip_header.htm") es;
mso-endnote-continuation-separator:url("file:///C:/Users/HUJIAN~1/AppData/Local/Temp/msohtmlclip1/01/clip_header.htm") ecs;}
@page Section1
{size:612.0pt 792.0pt;
margin:72.0pt 90.0pt 72.0pt 90.0pt;
mso-header-margin:36.0pt;
mso-footer-margin:36.0pt;
mso-paper-source:0;}
div.Section1
{page:Section1;}
-->
</style><!--[if gte mso 10]>
<style>
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:普通表格;
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-priority:99;
mso-style-qformat:yes;
mso-style-parent:"";
mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
mso-para-margin:0cm;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:10.5pt;
mso-bidi-font-size:11.0pt;
font-family:"Calibri","sans-serif";
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:宋体;
mso-fareast-theme-font:minor-fareast;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:"Times New Roman";
mso-bidi-theme-font:minor-bidi;
mso-font-kerning:1.0pt;}
</style>
<![endif]--><!--[if gte mso 9]><xml>
</xml><![endif]--><!--[if gte mso 9]><xml>
</xml><![endif]-->
<p><strong>[</strong><strong>问题描述]</strong></p>
<p>有一个环形的围墙，围墙上有一些塔，每个塔中有一个守卫。现在要发给每个守卫一些奖章，第i个守卫需要P[i]个奖章。每个守卫自己的奖章必须都是不同种类的，而且相邻的两个守卫得到的奖章也不能有任何一个相同。问至少应准备多少种不同的奖章。（限制：2&#8804;n&#8804;10000，1&#8804;P[i]&#8804;100000）</p>
<p><strong>[</strong><strong>分析]</strong></p>
<p>假如围墙不是环形的，我们很容易用贪心算法解决：每次发给守卫尽可能多的已准备的奖章，如果不够就再新准备若干种以满足需要。但现在围墙是环形的，最后一个守卫与第一个守卫也不能有重复的奖章，这就是问题的难点。</p>
<p>于是我们尝试将这一难点引入状态，用动态规划求解（动态规划是求解最优性问题的一种常用方法）。</p>
<p>令a[i,j]表示前i个守卫已安排妥当，且第i个守卫有j个奖章与第一个守卫相同，则除第一个守卫已有的P[1]种奖章外，至少还需要的奖章种数。</p>
<p><!--[if mso & !supportInlineShapes & supportFields]>&#160;SHAPE \* MERGEFORMAT <![endif]--><!--[if gte vml 1]>
<![if !mso]>
<table cellpadding="0" cellspacing="0" width="100%">
    <tr>
        <td><![endif]>
        <div>
        <p><strong style="'mso-bidi-font-weight:normal'">k</strong></p>
        </div>
        <![if !mso]></td>
    </tr>
</table>
<![endif]>
<![if !mso]>
<table cellpadding="0" cellspacing="0" width="100%">
    <tr>
        <td><![endif]>
        <div>
        <p><strong style="'mso-bidi-font-weight:normal'">P[i-1]-k</strong></p>
        </div>
        <![if !mso]></td>
    </tr>
</table>
<![endif]>
<![if !mso]>
<table cellpadding="0" cellspacing="0" width="100%">
    <tr>
        <td><![endif]>
        <div>
        <p><strong style="'mso-bidi-font-weight:normal'">j</strong></p>
        </div>
        <![if !mso]></td>
    </tr>
</table>
<![endif]>
<![if !mso]>
<table cellpadding="0" cellspacing="0" width="100%">
    <tr>
        <td><![endif]>
        <div>
        <p><strong style="'mso-bidi-font-weight:normal'">P[i]-j</strong></p>
        </div>
        <![if !mso]></td>
    </tr>
</table>
<![endif]>
<![if !mso]>
<table cellpadding="0" cellspacing="0" width="100%">
    <tr>
        <td><![endif]>
        <div>
        <p><strong style="'mso-bidi-font-weight:normal'">第i-1</strong><b
        style="'mso-bidi-font-weight:normal'">个守卫</strong></p>
        </div>
        <![if !mso]></td>
    </tr>
</table>
<![endif]>
<![if !mso]>
<table cellpadding="0" cellspacing="0" width="100%">
    <tr>
        <td><![endif]>
        <div>
        <p><strong style="'mso-bidi-font-weight:normal'">第i</strong><b
        style="'mso-bidi-font-weight:normal'">个守卫</strong></p>
        </div>
        <![if !mso]></td>
    </tr>
</table>
<![endif]>
<![if !mso]>
<table cellpadding="0" cellspacing="0" width="100%">
    <tr>
        <td><![endif]>
        <div>
        <p>与第一个守卫相同的奖章数目</p>
        <p>&nbsp;</p>
        </div>
        <![if !mso]></td>
    </tr>
</table>
<![endif]>
<![if !mso]>
<table cellpadding="0" cellspacing="0" width="100%">
    <tr>
        <td><![endif]>
        <div>
        <p>与第一个守卫不同的奖章数目</p>
        <p>&nbsp;</p>
        </div>
        <![if !mso]></td>
    </tr>
</table>
<![endif]>
<![endif]--><!--[if !vml]--><img src="file:///C:/Users/HUJIAN%7E1/AppData/Local/Temp/msohtmlclip1/01/clip_image001.gif" v:shapes="_x0000_s1026 _x0000_s1027 _x0000_s1028 _x0000_s1029 _x0000_s1030 _x0000_s1031 _x0000_s1032 _x0000_s1033 _x0000_s1034 _x0000_s1035 _x0000_s1036 _x0000_s1037 _x0000_s1038 _x0000_s1039 _x0000_s1040 _x0000_s1041 _x0000_s1042 _x0000_s1043 _x0000_s1044" height="179" width="361"><!--[endif]--><!--[if mso & !supportInlineShapes & supportFields]><![endif]--></p>
<p>如图，假设第i-1个守卫有k个奖章与第一个守卫相同，由于这k个奖章与第i个守卫的j个奖章必须互不相同，易知j+k&#8804;P[1]；又由于第i-1个守卫的另外P[i-1]-k个奖章必须与第i个守卫的另外P[i]-j个奖章不同，设需要增加X种奖章，则</p>
<p><strong>a[i-1,k]+X </strong><strong>&#8805; (P[i]-j)+(P[i-1]-k)</strong></p>
<p>得到<strong>X </strong><strong>&#8805; (P[i]-j)+(P[i-1]-k) - a[i-1,k]</strong></p>
<p>于是我们有</p>
<p><!--[if gte vml 1]>
<![endif]--><!--[if !vml]--><img src="file:///C:/Users/HUJIAN%7E1/AppData/Local/Temp/msohtmlclip1/01/clip_image003.gif" v:shapes="_x0000_i1028" height="55" width="473"><!--[endif]--><!--[if gte mso 9]><xml>
</xml><![endif]--></p>
<p>显然就这样做复杂度高达O(n*Pmax<sup>2</sup>)。即使使用了优化，也很难得到令人满意的结果，我们只得另辟蹊径。</p>
<p>考虑到<strong>如果有P[1]+X种奖章，存在一种分发方案满足要求，那么如果我们有P[1]+X+1种奖章，也一定存在可行方案</strong>（大不了其中一种我们不用）。这个性质非常重要，因为由此，我们可以就用二分枚举X，再逐个判断是否有可行方案的方法求得结果。</p>
<p>所以原先问题就转化为——如果我们已经知道共有P[1]+X种奖章，我们能否很快判断是否存在满足要求的分发方案呢？答案是肯定的。</p>
<p>方法仍旧是动态规划<a href="http://www.cppblog.com/bluesea147/admin/EditArticles.aspx?opt=1#_ftn1" name="_ftnref1" title=""><!--[if !supportFootnotes]-->[1]<!--[endif]--></a>，状态表示也类似，a[i,j]表示共有P[1]+X种奖章，前i个守卫已安排妥当，且第i个守卫有j个奖章与第一个守卫相同是否可能。</p>
<p>则状态转移变为：</p>
<p><!--[if gte vml 1]>
<![endif]--><!--[if !vml]--><img src="file:///C:/Users/HUJIAN%7E1/AppData/Local/Temp/msohtmlclip1/01/clip_image005.gif" v:shapes="_x0000_i1029" height="36" width="217"><!--[endif]--><!--[if gte mso 9]><xml>
</xml><![endif]--></p>
<p>表面上看状态转移仍旧很繁琐，k的取值有很多限制。但我们仔细观察，第二、三条合起来是<strong>P[i-1]+P[i]-X-j </strong><strong>&#8804; k &#8804; P[1]-j</strong>。</p>
<p>对于确定的i，k的取值范围在数轴上的表示是一条长度确定的线段，且线段的位置由j确定。原先第一条限制只不过是再给线段限定一个范围，去除多余无意义的部分（如图）。</p>
<p><!--[if mso & !supportInlineShapes & supportFields]>&#160;SHAPE \* MERGEFORMAT <![endif]--><!--[if gte vml 1]>
<![if !mso]>
<table cellpadding="0" cellspacing="0" width="100%">
    <tr>
        <td><![endif]>
        <div>
        <p><strong style="'mso-bidi-font-weight:normal'">P[i-1]</strong></p>
        </div>
        <![if !mso]></td>
    </tr>
</table>
<![endif]>
<![if !mso]>
<table cellpadding="0" cellspacing="0" width="100%">
    <tr>
        <td><![endif]>
        <div>
        <p>P[i-1]+P[i]-X-<strong style="'mso-bidi-font-weight:
"        normal'>j</strong></p>
        </div>
        <![if !mso]></td>
    </tr>
</table>
<![endif]>
<![if !mso]>
<table cellpadding="0" cellspacing="0" width="100%">
    <tr>
        <td><![endif]>
        <div>
        <p>P[1]-<strong style="'mso-bidi-font-weight:
"        normal'>j</strong></p>
        </div>
        <![if !mso]></td>
    </tr>
</table>
<![endif]>
<![if !mso]>
<table cellpadding="0" cellspacing="0" width="100%">
    <tr>
        <td><![endif]>
        <div>
        <p>k的取值范围</p>
        </div>
        <![if !mso]></td>
    </tr>
</table>
<![endif]>
<![if !mso]>
<table cellpadding="0" cellspacing="0" width="100%">
    <tr>
        <td><![endif]>
        <div>
        <p>多余的无意义部分</p>
        </div>
        <![if !mso]></td>
    </tr>
</table>
<![endif]>
<![if !mso]>
<table cellpadding="0" cellspacing="0" width="100%">
    <tr>
        <td><![endif]>
        <div>
        <p><strong style="'mso-bidi-font-weight:normal'">0</strong></p>
        </div>
        <![if !mso]></td>
    </tr>
</table>
<![endif]>
<![endif]--><!--[if !vml]--><img src="file:///C:/Users/HUJIAN%7E1/AppData/Local/Temp/msohtmlclip1/01/clip_image006.gif" v:shapes="_x0000_s1045 _x0000_s1046 _x0000_s1047 _x0000_s1048 _x0000_s1049 _x0000_s1050 _x0000_s1051 _x0000_s1052 _x0000_s1053 _x0000_s1054 _x0000_s1055 _x0000_s1056 _x0000_s1057 _x0000_s1058 _x0000_s1059 _x0000_s1060 _x0000_s1061" height="145" width="389"><!--[endif]--><!--[if mso & !supportInlineShapes & supportFields]><![endif]--></p>
<p>初始状态a[1]中只有a[1,0]=true，其余均为false。由归纳法很容易证明对任意i，a[i,j]中为true的j一定是连续的一段。由此对每个i，所有状态a[i,j]可仅用两个端点表示，即a[i].x1、a[i].x2。</p>
<p><!--[if mso & !supportInlineShapes & supportFields]>&#160;SHAPE \* MERGEFORMAT <![endif]--><!--[if gte vml 1]>
<![if !mso]>
<table cellpadding="0" cellspacing="0" width="100%">
    <tr>
        <td><![endif]>
        <div>
        <p>a[i-1].x1<b
        style="'mso-bidi-font-weight:normal'">1</strong></p>
        </div>
        <![if !mso]></td>
    </tr>
</table>
<![endif]>
<![if !mso]>
<table cellpadding="0" cellspacing="0" width="100%">
    <tr>
        <td><![endif]>
        <div>
        <p>a[i-1].x1</p>
        </div>
        <![if !mso]></td>
    </tr>
</table>
<![endif]>
<![if !mso]>
<table cellpadding="0" cellspacing="0" width="100%">
    <tr>
        <td><![endif]>
        <div>
        <p>a[i-1].x2</p>
        </div>
        <![if !mso]></td>
    </tr>
</table>
<![endif]>
<![if !mso]>
<table cellpadding="0" cellspacing="0" width="100%">
    <tr>
        <td><![endif]>
        <div>
        <p>a[i-1].x2</p>
        </div>
        <![if !mso]></td>
    </tr>
</table>
<![endif]>
<![if !mso]>
<table cellpadding="0" cellspacing="0" width="100%">
    <tr>
        <td><![endif]>
        <div>
        <p>P[i-1]+P[i]-X-j</p>
        </div>
        <![if !mso]></td>
    </tr>
</table>
<![endif]>
<![if !mso]>
<table cellpadding="0" cellspacing="0" width="100%">
    <tr>
        <td><![endif]>
        <div>
        <p>P[i-1]+P[i]-X-j</p>
        </div>
        <![if !mso]></td>
    </tr>
</table>
<![endif]>
<![if !mso]>
<table cellpadding="0" cellspacing="0" width="100%">
    <tr>
        <td><![endif]>
        <div>
        <p>P[1]-j</p>
        </div>
        <![if !mso]></td>
    </tr>
</table>
<![endif]>
<![if !mso]>
<table cellpadding="0" cellspacing="0" width="100%">
    <tr>
        <td><![endif]>
        <div>
        <p>P[1]-j</p>
        </div>
        <![if !mso]></td>
    </tr>
</table>
<![endif]>
<![if !mso]>
<table cellpadding="0" cellspacing="0" width="100%">
    <tr>
        <td><![endif]>
        <div>
        <p>k的取值范围</p>
        </div>
        <![if !mso]></td>
    </tr>
</table>
<![endif]>
<![if !mso]>
<table cellpadding="0" cellspacing="0" width="100%">
    <tr>
        <td><![endif]>
        <div>
        <p>k的取值范围</p>
        </div>
        <![if !mso]></td>
    </tr>
</table>
<![endif]>
<![endif]--><!--[if !vml]--><img src="file:///C:/Users/HUJIAN%7E1/AppData/Local/Temp/msohtmlclip1/01/clip_image007.gif" v:shapes="_x0000_s1062 _x0000_s1063 _x0000_s1064 _x0000_s1065 _x0000_s1066 _x0000_s1067 _x0000_s1068 _x0000_s1069 _x0000_s1070 _x0000_s1071 _x0000_s1072 _x0000_s1073 _x0000_s1074 _x0000_s1075 _x0000_s1076 _x0000_s1077 _x0000_s1078 _x0000_s1079 _x0000_s1080 _x0000_s1081" height="134" width="469"><!--[endif]--><!--[if mso & !supportInlineShapes & supportFields]><![endif]--></p>
<p>考虑要使a[i,j]=true，当且仅当k的取值范围与线段<strong>[</strong>a[i-1].x1<strong>,</strong>a[i-1].x2<strong>]</strong>有交集，即满足</p>
<p><strong>P[1]-j </strong><strong>&#8805; a[i-1].x1&nbsp; </strong>and<strong>&nbsp; P[i-1]+P[i]-X-j
</strong><strong>&#8804; a[i-1].x2</strong></p>
<p>即 <strong>P[i-1]+P[i]-X-a[i-1].x2 </strong><strong>&#8804; j &#8804; P[1]-a[i-1].x2</strong></p>
<p>由此，状态转移方程变为：</p>
<p><strong>a[i].x1=max( 0 ,
P[i-1]+P[i]-X-a[i-1].x2 )</strong></p>
<p><strong>a[i].x2=min( P[i] ,
P[1]-a[i-1].x1 )</strong></p>
<p>初始状态a[1].x1=a[1].x2=P[1]，状态总数O(n)，状态转移O(1)，可以说是高效的。</p>
<p>有了此方法，鉴于先前的分析，我们采用二分枚举X，并利用高效的测试方法，即可在O(n*logPmax)的时间解决整个问题。</p>
<p><strong>[</strong><strong>小结]</strong></p>
<p>上面这个问题，看似难点仍旧在于动态规划，二分枚举只不过充当了一个附加手段。但实际上事先枚举的X，极大地简便了动态规划的方程，才使得问题得以解决。应用这类二分枚举思想的最优性问题近来很是热门，而且这类试题很容易诱导选手直接采用动态规划或是贪心算法，而走入死胡同。</p>
<p>所以，今后我们在考虑最优性问题时，应注意问题是否隐含了一个有序的01序列，它是否可以用二分枚举的方法将最优性问题转化为可行性问题。切记！&#8220;退一步海阔天空&#8221;。</p>
<div><!--[if !supportFootnotes]--><br clear="all">
<hr align="left" size="1" width="33%">
<!--[endif]-->
<div id="ftn1">
<p><a href="http://www.cppblog.com/bluesea147/admin/EditArticles.aspx?opt=1#_ftnref1" name="_ftn1" title=""><!--[if !supportFootnotes]-->[1]<!--[endif]--></a> 准确地说应该是递推</p>
</div>
</div>
<br><img src ="http://www.cppblog.com/bluesea147/aggbug/122780.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/bluesea147/" target="_blank">蓝色的大海</a> 2010-08-09 15:01 <a href="http://www.cppblog.com/bluesea147/articles/122780.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>二分法浅谈 (1)</title><link>http://www.cppblog.com/bluesea147/articles/122774.html</link><dc:creator>蓝色的大海</dc:creator><author>蓝色的大海</author><pubDate>Mon, 09 Aug 2010 06:44:00 GMT</pubDate><guid>http://www.cppblog.com/bluesea147/articles/122774.html</guid><wfw:comment>http://www.cppblog.com/bluesea147/comments/122774.html</wfw:comment><comments>http://www.cppblog.com/bluesea147/articles/122774.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/bluesea147/comments/commentRss/122774.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/bluesea147/services/trackbacks/122774.html</trackback:ping><description><![CDATA[<meta http-equiv="Content-Type" content="text/html; charset=" utf-8="">
<meta name="ProgId" content="Word.Document">
<meta name="Generator" content="Microsoft Word 12">
<meta name="Originator" content="Microsoft Word 12">
<link rel="File-List" href="file:///C:%5CUsers%5CHUJIAN%7E1%5CAppData%5CLocal%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_filelist.xml">
<link rel="Edit-Time-Data" href="file:///C:%5CUsers%5CHUJIAN%7E1%5CAppData%5CLocal%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_editdata.mso"><!--[if !mso]>
<style>
v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
</style>
<![endif]-->
<link rel="themeData" href="file:///C:%5CUsers%5CHUJIAN%7E1%5CAppData%5CLocal%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_themedata.thmx">
<link rel="colorSchemeMapping" href="file:///C:%5CUsers%5CHUJIAN%7E1%5CAppData%5CLocal%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_colorschememapping.xml"><!--[if gte mso 9]><xml>
Normal
0
7.8 磅
0
2
false
false
false
EN-US
ZH-CN
X-NONE
MicrosoftInternetExplorer4
</xml><![endif]--><!--[if gte mso 9]><xml>
</xml><![endif]--><style>
<!--
/* Font Definitions */
@font-face
{font-family:Wingdings;
panose-1:5 0 0 0 0 0 0 0 0 0;
mso-font-charset:2;
mso-generic-font-family:auto;
mso-font-pitch:variable;
mso-font-signature:0 268435456 0 0 -2147483648 0;}
@font-face
{font-family:宋体;
panose-1:2 1 6 0 3 1 1 1 1 1;
mso-font-alt:SimSun;
mso-font-charset:134;
mso-generic-font-family:auto;
mso-font-pitch:variable;
mso-font-signature:3 680460288 22 0 262145 0;}
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;
mso-font-charset:0;
mso-generic-font-family:roman;
mso-font-pitch:variable;
mso-font-signature:-1610611985 1107304683 0 0 415 0;}
@font-face
{font-family:华文新魏;
panose-1:2 1 8 0 4 1 1 1 1 1;
mso-font-charset:134;
mso-generic-font-family:auto;
mso-font-pitch:variable;
mso-font-signature:1 135200768 16 0 262144 0;}
@font-face
{font-family:"\@宋体";
panose-1:2 1 6 0 3 1 1 1 1 1;
mso-font-charset:134;
mso-generic-font-family:auto;
mso-font-pitch:variable;
mso-font-signature:3 680460288 22 0 262145 0;}
@font-face
{font-family:"\@华文新魏";
panose-1:2 1 8 0 4 1 1 1 1 1;
mso-font-charset:134;
mso-generic-font-family:auto;
mso-font-pitch:variable;
mso-font-signature:1 135200768 16 0 262144 0;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{mso-style-unhide:no;
mso-style-qformat:yes;
mso-style-parent:"";
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
mso-pagination:none;
font-size:10.5pt;
mso-bidi-font-size:10.0pt;
font-family:"Times New Roman","serif";
mso-fareast-font-family:宋体;
mso-font-kerning:1.0pt;}
.MsoChpDefault
{mso-style-type:export-only;
mso-default-props:yes;
font-size:10.0pt;
mso-ansi-font-size:10.0pt;
mso-bidi-font-size:10.0pt;
mso-ascii-font-family:Calibri;
mso-fareast-font-family:宋体;
mso-hansi-font-family:Calibri;
mso-font-kerning:0pt;}
/* Page Definitions */
@page
{mso-page-border-surround-header:no;
mso-page-border-surround-footer:no;}
@page Section1
{size:612.0pt 792.0pt;
margin:72.0pt 90.0pt 72.0pt 90.0pt;
mso-header-margin:36.0pt;
mso-footer-margin:36.0pt;
mso-paper-source:0;}
div.Section1
{page:Section1;}
-->
</style><!--[if gte mso 10]>
<style>
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:普通表格;
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-priority:99;
mso-style-qformat:yes;
mso-style-parent:"";
mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
mso-para-margin:0cm;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:10.5pt;
mso-bidi-font-size:11.0pt;
font-family:"Calibri","sans-serif";
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:宋体;
mso-fareast-theme-font:minor-fareast;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:"Times New Roman";
mso-bidi-theme-font:minor-bidi;
mso-font-kerning:1.0pt;}
</style>
<![endif]--><!--[if gte mso 9]><xml>
</xml><![endif]--><!--[if gte mso 9]><xml>
</xml><![endif]-->
<p><strong>[</strong><strong>问题描述]</strong></p>
<p>有N头奶牛（N是2<sup>K</sup>），都是网球高手，每头奶牛都有一个BTP排名（恰好为1—N）。下周将要进行一场淘汰赛，N头奶牛分成N/2组，每组两头奶牛比赛，决出N/2位胜者；N/2位胜者继而分成N/4组比赛&#8230;&#8230;直至剩下一头牛是冠军。</p>
<p>比赛既要讲求实力，又要考虑到运气。如果两头奶牛的BTP排名相差大于给定整数K，则排名靠前的奶牛总是赢排名靠后的；否则，双方都有可能获胜。现在观众们想知道，哪头奶牛是所有可能成为冠军的牛中排名最后的，并要求你列举出一个可能的比赛安排使该奶牛获胜。（限制N&#8804;65536）</p>
<p><strong>[</strong><strong>分析]</strong></p>
<p>由于N很大，我们猜想可以通过贪心方法解决。</p>
<p>我们希望排名靠前的选手总是&#8220;爆冷&#8221;输给排名靠后的选手。于是我们让1输给K+1、2输给K+2&#8230;&#8230;每一轮中每一局总是选择未比赛的排名最前的选手，输给一个排名最靠后的选手（如果有的话）。</p>
<p>但我们很容易找到反例，例如：N=8,
K=2，由上述贪心方法我们得到对阵方式结果为4，见图BTP-1（其中X&#224;Y表示X战胜Y）。</p>
<p><!--[if mso & !supportInlineShapes & supportFields]>&#160;SHAPE \* MERGEFORMAT <![endif]--><!--[if gte vml 1]>
<![if !mso]>
<table cellpadding="0" cellspacing="0" width="100%">
    <tr>
        <td><![endif]>
        <div>
        <p><strong style="'mso-bidi-font-weight:
        "        normal'>3</strong><strong style="'mso-bidi-font-weight:
        "        normal'>&#224;</strong><b
        style="'mso-bidi-font-weight:normal'">1&#160; 4</strong><strong style="'mso-bidi-font-weight:
        "        normal'>&#224;</strong><b
        style="'mso-bidi-font-weight:normal'">2&#160; 7</strong><strong style="'mso-bidi-font-weight:
        "        normal'>&#224;</strong><b
        style="'mso-bidi-font-weight:normal'">5&#160; 8</strong><strong style="'mso-bidi-font-weight:
        "        normal'>&#224;</strong><b
        style="'mso-bidi-font-weight:normal'">6</strong></p>
        <p><strong style="'mso-bidi-font-weight:
        "        normal'>4</strong><strong style="'mso-bidi-font-weight:
        "        normal'>&#224;</strong><b
        style="'mso-bidi-font-weight:normal'">3&#160; &#160;&#160;&#160;&#160;&#160;&#160;8</strong><strong style="'mso-bidi-font-weight:
        "        normal'>&#224;</strong><b
        style="'mso-bidi-font-weight:normal'">7</strong></p>
        <p><b
        style="'mso-bidi-font-weight:normal'">4</strong><b
        style="'mso-bidi-font-weight:normal'">&#224;</strong><b
        style="'mso-bidi-font-weight:normal'">8</strong></p>
        </div>
        <![if !mso]></td>
    </tr>
</table>
<![endif]>
<![if !mso]>
<table cellpadding="0" cellspacing="0" width="100%">
    <tr>
        <td><![endif]>
        <div>
        <p><strong style="'mso-bidi-font-weight:
        "        normal'>6</strong><strong style="'mso-bidi-font-weight:
        "        normal'>&#224;</strong><b
        style="'mso-bidi-font-weight:normal'">7&#160; 5</strong><strong style="'mso-bidi-font-weight:
        "        normal'>&#224;</strong><b
        style="'mso-bidi-font-weight:normal'">3&#160; 4</strong><strong style="'mso-bidi-font-weight:
        "        normal'>&#224;</strong><b
        style="'mso-bidi-font-weight:normal'">8&#160; 2</strong><strong style="'mso-bidi-font-weight:
        "        normal'>&#224;</strong><b
        style="'mso-bidi-font-weight:normal'">1</strong></p>
        <p><b
        style="'mso-bidi-font-weight:normal'">6</strong><b
        style="'mso-bidi-font-weight:normal'">&#224;</strong><b
        style="'mso-bidi-font-weight:normal'">5&#160; &#160;&#160;&#160;&#160;&#160;&#160;4</strong><strong style="'mso-bidi-font-weight:
        "        normal'>&#224;</strong><b
        style="'mso-bidi-font-weight:normal'">2</strong></p>
        <p><b
        style="'mso-bidi-font-weight:normal'">6</strong><b
        style="'mso-bidi-font-weight:normal'">&#224;</strong><b
        style="'mso-bidi-font-weight:normal'">4</strong></p>
        </div>
        <![if !mso]></td>
    </tr>
</table>
<![endif]>
<![endif]--><!--[if !vml]--><img src="file:///C:/Users/HUJIAN%7E1/AppData/Local/Temp/msohtmlclip1/01/clip_image001.gif" v:shapes="_x0000_s1026 _x0000_s1027 _x0000_s1028 _x0000_s1029" height="80" width="442"><!--[endif]--><!--[if mso & !supportInlineShapes & supportFields]><![endif]--></p>
<p>&nbsp;&nbsp;&nbsp; 图BTP-1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
图BTP-2</p>
<p>但最优解为6，见图BTP-2。究其原因，因为我们不知道最优解是多少，所以我们是在盲目地贪心。事实上，最优解的6在第一轮就被我们淘汰了，当然就得不到最优解喽！</p>
<p>要想知道最优解？枚举！同时考虑到一个很显然的结论——<strong>如果排名为X的选手最终获胜，那么排名在X前的选手也可以获胜</strong>。</p>
<p>显然归显然，证明它我们还需要动一点小脑筋。假设排名X的选手最终获胜，我们通过对该对战方式的局部修改，构造出一种新的对战方式使任意排名Y&lt;X的选手获胜：在X最终获胜的对战方式中，假设Y是被Z击败。如果Z&#8800;X，由X&gt;Y，可知Z一定也能击败X，且同一轮及此后X所击败的选手都能被Y击败，所以我们只需要在此轮让Z击败X，并把之后所有对战中的X都改成Y即可；如果Z=X，由X&gt;Y，我们就让Y击败X，同样把之后对战中的X都改成Y，则最后获胜的也是Y。</p>
<p>因此，我们就可以用二分枚举最终获胜的X，大大提高了算法效率。</p>
<p>现在的问题是，如果我们知道最终获胜的是X，我们能否很快构造出一种对战方式或是证明不存在吗？可以，我们仍旧使用贪心，不过因为我们知道最终谁获胜，所以我们采用倒推。</p>
<p>每一轮，我们都让已有选手去战胜一个排名最靠前的还未出现的选手，由该方法产生的对战方式就如图BTP-2所描述那样。至于最靠前的未出现选手如何找，我们可以采用静态排序二叉树实现，这里不再展开，读者可以自己考虑。</p>
<p>可以证明这样贪心是正确的（证明方法同前面的证明类似，这里也不再重复）。整个问题可以在O(Nlog<sup>2</sup>N)时间完成。</p>
<p><strong>[</strong><strong>小结]</strong></p>
<p>对于这类需要二分枚举的问题，其实算法的根本是在一个隐含的退化了的有序序列中进行二分查找，只是这个序列仅含有0和1两种值。上例中当X&lt;Ans，A[X]=0；当X&#8805;Ans，A[X]=1。而我们所寻找的就是这两种值的分界点。有了分界点，就有了最优值，也就有了原问题的解。</p>
<br> <img src ="http://www.cppblog.com/bluesea147/aggbug/122774.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/bluesea147/" target="_blank">蓝色的大海</a> 2010-08-09 14:44 <a href="http://www.cppblog.com/bluesea147/articles/122774.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>