﻿<?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++博客-Residence for sdfond-随笔分类-算法 - 动态规划</title><link>http://www.cppblog.com/sdfond/category/9807.html</link><description>世事洞明皆学问，人情练达即文章</description><language>zh-cn</language><lastBuildDate>Sun, 07 Feb 2010 16:46:21 GMT</lastBuildDate><pubDate>Sun, 07 Feb 2010 16:46:21 GMT</pubDate><ttl>60</ttl><item><title>UVa 861 Little Bishops</title><link>http://www.cppblog.com/sdfond/archive/2010/02/06/107392.html</link><dc:creator>sdfond</dc:creator><author>sdfond</author><pubDate>Sat, 06 Feb 2010 09:58:00 GMT</pubDate><guid>http://www.cppblog.com/sdfond/archive/2010/02/06/107392.html</guid><wfw:comment>http://www.cppblog.com/sdfond/comments/107392.html</wfw:comment><comments>http://www.cppblog.com/sdfond/archive/2010/02/06/107392.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sdfond/comments/commentRss/107392.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sdfond/services/trackbacks/107392.html</trackback:ping><description><![CDATA[【题目大意】<br>　　给定一个n*n的棋盘，求放置k个互不攻击的象的方法数。其中n &lt;= 8，k &lt;= n ^
2。<br><br>【题目分析】<br>　　对于棋盘放车问题可以用组合数学的知识来解决，但是对于含禁区的摆放问题，虽然组合数学给出了经典的棋盘多项式+容斥原理的解法，但是实际中棋盘多项式的求解是很困难的，因此一般需要借助状态压缩动态规划求解。<br>　　现在题目中要求出互不攻击的象的方法数，象的攻击路线是斜的，是不是可以考虑采用放车的方法来解呢？将棋盘黑白染色，如果一个象在黑色的格子里面，那么它一定不会攻击到白色的格子，这样的话可以分开计数，然后最后利用乘法原理加起来就行了。把棋盘旋转45度，这样象的攻击路线就是直的了，如果只考虑一种颜色的话，那么问题就转变成了经典的放车问题了，可以利用动态规划解决。<br>　　设dp[i][j]表示前i行放了j个车的方法数，c[i]表示第i行可以放置的棋子数量，那么转移方程为：<br>　　　　dp[i][j]
= dp[i-1][j] + dp[i-1][j-1] * (c[i] - (j -
1))<br>　　需要注意的是c数组应该是增序的，这样才能保证前面的j-1行放了车，对应这一行就有j-1个位置不可放了。<br>　　这个题目的dp方程不难想，但是如何把模型转化到放车问题是不容易想到的，尤其是将棋盘黑白染色后分开计数的想法，非常巧妙。<br>
<br>题目代码：
<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008080;">&nbsp;1</span>&nbsp;<span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">iostream</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">algorithm</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">using</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">namespace</span><span style="color: #000000;">&nbsp;std;<br></span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;N&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">70</span><span style="color: #000000;">;<br></span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;init(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;n,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;c1[N],&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;c2[N])<br></span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;memset(c1,&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">,&nbsp;</span><span style="color: #0000ff;">sizeof</span><span style="color: #000000;">(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">)&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;N);<br></span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;memset(c2,&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">,&nbsp;</span><span style="color: #0000ff;">sizeof</span><span style="color: #000000;">(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">)&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;N);<br></span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">;&nbsp;i&nbsp;</span><span style="color: #000000;">&lt;=</span><span style="color: #000000;">&nbsp;n;&nbsp;i</span><span style="color: #000000;">++</span><span style="color: #000000;">)<br></span><span style="color: #008080;">11</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">12</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;j&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">;&nbsp;j&nbsp;</span><span style="color: #000000;">&lt;=</span><span style="color: #000000;">&nbsp;n;&nbsp;j</span><span style="color: #000000;">++</span><span style="color: #000000;">)<br></span><span style="color: #008080;">13</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">14</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;((i&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;j)&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">)<br></span><span style="color: #008080;">15</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;c2[(i</span><span style="color: #000000;">+</span><span style="color: #000000;">j)</span><span style="color: #000000;">/</span><span style="color: #000000;">2</span><span style="color: #000000;">]</span><span style="color: #000000;">++</span><span style="color: #000000;">;<br></span><span style="color: #008080;">16</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;"><br></span><span style="color: #008080;">17</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;c1[(i</span><span style="color: #000000;">+</span><span style="color: #000000;">j)</span><span style="color: #000000;">/</span><span style="color: #000000;">2</span><span style="color: #000000;">]</span><span style="color: #000000;">++</span><span style="color: #000000;">;<br></span><span style="color: #008080;">18</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">19</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">20</span>&nbsp;<span style="color: #000000;">}<br></span><span style="color: #008080;">21</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;bishops(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;n,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;dp[N][N],&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;c[N])<br></span><span style="color: #008080;">22</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">23</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;i&nbsp;</span><span style="color: #000000;">&lt;=</span><span style="color: #000000;">&nbsp;n;&nbsp;i</span><span style="color: #000000;">++</span><span style="color: #000000;">)<br></span><span style="color: #008080;">24</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dp[i][</span><span style="color: #000000;">0</span><span style="color: #000000;">]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br></span><span style="color: #008080;">25</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">;&nbsp;i&nbsp;</span><span style="color: #000000;">&lt;=</span><span style="color: #000000;">&nbsp;n;&nbsp;i</span><span style="color: #000000;">++</span><span style="color: #000000;">)<br></span><span style="color: #008080;">26</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;j&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">;&nbsp;j&nbsp;</span><span style="color: #000000;">&lt;=</span><span style="color: #000000;">&nbsp;c[i];&nbsp;j</span><span style="color: #000000;">++</span><span style="color: #000000;">)<br></span><span style="color: #008080;">27</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dp[i][j]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;dp[i</span><span style="color: #000000;">-</span><span style="color: #000000;">1</span><span style="color: #000000;">][j]&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;dp[i</span><span style="color: #000000;">-</span><span style="color: #000000;">1</span><span style="color: #000000;">][j</span><span style="color: #000000;">-</span><span style="color: #000000;">1</span><span style="color: #000000;">]&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;(c[i]&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;j&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">);<br></span><span style="color: #008080;">28</span>&nbsp;<span style="color: #000000;">}<br></span><span style="color: #008080;">29</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">30</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;main()<br></span><span style="color: #008080;">31</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">32</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;n,&nbsp;k,&nbsp;c1[N],&nbsp;c2[N],&nbsp;dp1[N][N],&nbsp;dp2[N][N],&nbsp;ans;<br></span><span style="color: #008080;">33</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">34</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;(scanf(</span><span style="color: #000000;">"</span><span style="color: #000000;">%d&nbsp;%d</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">n,&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">k)&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">2</span><span style="color: #000000;">)<br></span><span style="color: #008080;">35</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">36</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(n&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">&nbsp;k&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">)<br></span><span style="color: #008080;">37</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">break</span><span style="color: #000000;">;<br></span><span style="color: #008080;">38</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;init(n,&nbsp;c1,&nbsp;c2);<br></span><span style="color: #008080;">39</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sort(c1&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">,&nbsp;c1&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;n&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">);<br></span><span style="color: #008080;">40</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sort(c2&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">,&nbsp;c2&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;n);<br></span><span style="color: #008080;">41</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;memset(dp1,&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">,&nbsp;</span><span style="color: #0000ff;">sizeof</span><span style="color: #000000;">(dp1));<br></span><span style="color: #008080;">42</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;memset(dp2,&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">,&nbsp;</span><span style="color: #0000ff;">sizeof</span><span style="color: #000000;">(dp2));<br></span><span style="color: #008080;">43</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bishops(n,&nbsp;dp1,&nbsp;c1);<br></span><span style="color: #008080;">44</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bishops(n&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">,&nbsp;dp2,&nbsp;c2);<br></span><span style="color: #008080;">45</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ans&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br></span><span style="color: #008080;">46</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;i&nbsp;</span><span style="color: #000000;">&lt;=</span><span style="color: #000000;">&nbsp;k;&nbsp;i</span><span style="color: #000000;">++</span><span style="color: #000000;">)<br></span><span style="color: #008080;">47</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ans&nbsp;</span><span style="color: #000000;">+=</span><span style="color: #000000;">&nbsp;dp1[n][i]&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;dp2[n</span><span style="color: #000000;">-</span><span style="color: #000000;">1</span><span style="color: #000000;">][k</span><span style="color: #000000;">-</span><span style="color: #000000;">i];<br></span><span style="color: #008080;">48</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000;">"</span><span style="color: #000000;">%d\n</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;ans);<br></span><span style="color: #008080;">49</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">50</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">51</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br></span><span style="color: #008080;">52</span>&nbsp;<span style="color: #000000;">}</span></div>
<br>注：本文作于2009年6月23日 19点51分<br><br><img src ="http://www.cppblog.com/sdfond/aggbug/107392.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sdfond/" target="_blank">sdfond</a> 2010-02-06 17:58 <a href="http://www.cppblog.com/sdfond/archive/2010/02/06/107392.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>组合游戏总结——基本博弈问题</title><link>http://www.cppblog.com/sdfond/archive/2010/02/06/107364.html</link><dc:creator>sdfond</dc:creator><author>sdfond</author><pubDate>Sat, 06 Feb 2010 00:55:00 GMT</pubDate><guid>http://www.cppblog.com/sdfond/archive/2010/02/06/107364.html</guid><wfw:comment>http://www.cppblog.com/sdfond/comments/107364.html</wfw:comment><comments>http://www.cppblog.com/sdfond/archive/2010/02/06/107364.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sdfond/comments/commentRss/107364.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sdfond/services/trackbacks/107364.html</trackback:ping><description><![CDATA[<p>【概述】<br>　　最近的几次比赛，博弈的题目一直不少，而且博弈问题是一块比较复杂、庞大的内容，因此在这里小结一下，希望能够帮自己理清一些思路，争取也多来几个系列，呵呵。</p>
竞赛中出现的组合游戏问题一般都满足以下特征：<br>　　　　1.
二人博弈游戏，每个人都采用对自己最有利的策略，并且是两个人轮流做出决策<br>　　　　2.
在游戏中的任意时刻，每个玩家可选择的状态是固定的，没有随机成分<br>　　　　3.
游戏在有限步数内结束，没有平局出现<br>　　大部分的题目都满足上述条件，因此这里只讨论在上述条件范畴内的博弈问题。这类博弈问题，通常还有若干分类。一种是规定移动最后一步的游戏者获胜，这种规则叫做<span style="color: red;">Normal Play Rule</span>；另一种是规定移动最后一步的游戏者输，这种规则叫做<span style="color: red;">Misere Play
Rule</span>，也称为Anti-SG游戏。此外，对于游戏的双方，如果二者博弈的规则相同，那么称为这类游戏是<span style="color: red;">对等</span>(impartial games)的；否则称为<span style="color: red;">不平等游戏</span>(partizan games
)。当初WHU的那场比赛就是由于对于这个概念不是很清晰，导致看完题目之后就用SG定理来做，浪费了很多机时。实际上，解决不平等博弈问题的方法和普通的博弈问题（SG游戏）是有区别的，一般会采用动态规划或者surreal number。<br><br>【博弈基础知识】<br>　　在SG游戏中，最为人熟知的是必胜必败态，也叫NP态理论。注意的是，P态对应的是先手必败态，N态对应的是先手必胜态。必胜必败态理论是：<br>　　1. All terminal positions are
P-positions<br>　　2. From every
N-position, there is at least one move to a P-position<br>　　3. From every P-position, every move is to an
N-position<br>　　英文的表述非常简洁清晰，而且这个理论也很好理解，如果在当前状态的下一步可以走到必败态，那么当前玩家就可以走到那个状态，把必败态推给另一方；如果所有可达状态都是必胜态，那么当前玩家无论如何走，都会把必胜态让给对方。根据必胜必败态理论，我们可以递归的求出每个状态是N态还是P态。必胜必败态理论其实已经把博弈问题转化成了一个有向图，借助图这个模型来分析问题，使得问题变得形象了许多。需要注意的是，这种SG游戏对应的有向图是无环的，因为如果有环，那么游戏双方就可能在环上不停的转换状态，游戏不能在有限步终止，这样就不满足组合游戏的特征3了。<br>　　然而在很多时候仅仅知道某个状态是必胜还是必败是不够的，因为如果存在多个组合游戏（比如经典的Nim），对应的状态集合非常大，无法直接利用必胜必败态理论求解，因此需要用到博弈论中一个很重要的工具：SG函数。<br>　　某个状态的SG函数值定义为当前状态所有不可达的状态编号中最小的编号，其中终止态的SG函数值是0。有了这个工具，就引入一个非常强大的定理——SG分解定理：<br><br>　　<span style="background-color: #ffffff; color: red;">多个组合游戏的SG函数值是每个组合游戏的函数值的和。</span>（这里的和定义为异或操作）<br>　　<br>　　SG分解定理的证明不是很难，其实和Nim的证明很像。根据这个定理，我们就知道为什么Nim的解法是异或所有的石子个数了，因为每堆石子的SG值就是石子的个数。SG分解定理告诉我们任何SG游戏都可以转化成Nim游戏来做。<br>　　Nim中的一个变形就是拿走最后一块石子的人算输。通过修改SG的计算规则，可以得出相同的结论（因为当石子个数是1的时候SG值为0，因此要单独处理）；当然也可以利用一个叫做SJ定理的方法来做，依然是要处理当所有堆的SG值不大于1的情况。<br><br>【博弈基本模型】<br>　　除了Nim模型，很多模型都看似复杂，最后都划归到了Nim模型上，然后利用SG分解来做的。在证明两种模型等价的时候，可以通过计算SG值判断是否相同，或者通过判断必胜策略的走法将其转化为Nim。许多模型非常的神奇，其获胜策略又千差万别，因此无法一一列举，但是掌握一些经典模型是必须的，这样通过模型的转化可以简化问题的难度。<br>　　<span style="background-color: yellow;">经典模型1：Nim变种。</span>包括：<br>　　　　(1)
楼梯Nim。把奇数台阶的石子作为Nim，二者等价，因为必胜的策略是相同的。<br>　　　　(2) 每次可以取k堆，这个是经典的Moore
Nim。它是泛化的Nim游戏。<br>　　　　(3)
两堆石子，每次可以取一堆或两堆，从两堆取得时候个数必须相同，谁先取完获胜。这个是著名的威佐夫博弈，跟黄金分割数有关，具体证明不是很清楚，但是用SG值打表可以找出规律。代码如下：
<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">cstdio</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br>#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">cmath</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br>#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">algorithm</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">using</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">namespace</span><span style="color: #000000;">&nbsp;std;<br><br></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;main()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">double</span><span style="color: #000000;">&nbsp;k&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(sqrt(</span><span style="color: #000000;">5.0</span><span style="color: #000000;">)&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">)&nbsp;</span><span style="color: #000000;">/</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">2.0</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;a,&nbsp;b,&nbsp;t;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;(scanf(</span><span style="color: #000000;">"</span><span style="color: #000000;">%d&nbsp;%d</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">a,&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">b)&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">2</span><span style="color: #000000;">)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(a&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;b)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;swap(a,&nbsp;b);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;b&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;a;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(a&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">)(t&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;k))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts(</span><span style="color: #000000;">"</span><span style="color: #000000;">0</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts(</span><span style="color: #000000;">"</span><span style="color: #000000;">1</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br>}</span></div>
<br>　　　　(4) Subtraction
Games。一种通用的Nim游戏，每次从可用状态集合中选择下一步的状态，有很多变形，核心思想还是计算SG函数值。<br>　　　　(5)
Take-and-Break Game。每次把局面分成多个Nim子游戏，利用SG分解定理求出对应的SG值。<br>　　<span style="background-color: yellow;">经典模型2：翻硬币游戏(Coin Turning
Game)</span><br>　　　　(1) 一维的翻硬币游戏，每次可以翻1个或两个。通过单独考虑每个可以翻的硬币发现，Coin Turning
Game的SG值和Nim等价，因此两个模型等价。需要注意的是，许多翻硬币游戏根据题目的要求，一般编号从0开始。<br>　　　　(2)
一维的翻硬币游戏，每次可以翻1个或两个，限定了翻第二枚硬币的范围，那么就和Subtraction Game等价了。<br>　　　　(3)
一维的翻硬币游戏，每次可以翻1个、2个或3个，这个游戏叫做Mock Turtles，有一个神奇的规律，是Odious Number序列。<br>　　　　(4)
高维的翻硬币游戏，需要用到Nim积和Tartan定理。<br>　　翻硬币模型的变化更多，很多模型都有一些奇妙的规律，需要打表才能发现。<br>　　<span style="background-color: yellow;">经典模型3：删边游戏(Green Hackenbush)</span><br>　　　　(1)
树的删边游戏：Colon原理证明这种模型和Nim依然是等价的，多个叉的SG值异或就是对应根节点的SG值。<br>　　　　(2)
无向图删边游戏：利用Fursion定理收缩圈，然后就转换成树的删边游戏了，不过这个定理还不会证。
<br><br>注：本文作于2009年8月3日 09点33分<br><br>  <img src ="http://www.cppblog.com/sdfond/aggbug/107364.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sdfond/" target="_blank">sdfond</a> 2010-02-06 08:55 <a href="http://www.cppblog.com/sdfond/archive/2010/02/06/107364.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一个棋盘覆盖问题</title><link>http://www.cppblog.com/sdfond/archive/2009/12/12/103070.html</link><dc:creator>sdfond</dc:creator><author>sdfond</author><pubDate>Sat, 12 Dec 2009 12:10:00 GMT</pubDate><guid>http://www.cppblog.com/sdfond/archive/2009/12/12/103070.html</guid><wfw:comment>http://www.cppblog.com/sdfond/comments/103070.html</wfw:comment><comments>http://www.cppblog.com/sdfond/archive/2009/12/12/103070.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sdfond/comments/commentRss/103070.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sdfond/services/trackbacks/103070.html</trackback:ping><description><![CDATA[　　昨天看到名为&#8220;矩阵也疯狂&#8221;的帖子，老帖了，不过都是很有意思、很经典的题目。其中的第四题是说一个3*n的棋盘用1*2的棋子覆盖，求有多少种覆盖方法，结果模m，其中m、n &lt; 2 ^ 32。<br>　　不考虑数据范围，一个O(n^2)的dp很容易想到，设f[n]是所求答案，n是奇数结果为0，否则有：<br>　　　　f[n] = f[n-2] * 3 + f[n-4] * 2 + f[n-6] * 2 + ...<br>　　一个2 * 3的棋盘有3种摆法，一个4*3的棋盘需要相互交错的摆放，因此有2种摆法，其余依次类推。<br>　　但是这个递推方程对于这样的数据量肯定是无法接受的。将方程进行化简：<br>　　　　f[n] = f[n-2] * 3 + (3 * f[n-4] + f[n-6] * 2 + ...) - f[n-4]<br>　　　　　　 = f[n-2] * 3 + f[n-2] - f[n-4]<br>　　　　　　 = 4 * f[n-2] - f[n-4]<br>　　这样就转化成了线性递推方程，可以用矩阵来做了。<br>　　话说这个题目我在HOJ上做的时候因为数据小就直接O(n^2)了，看来对于一个题目仔细思考、发散思维还是很重要的。<br>　　既然3*n的可以做，那么4*n应该也可以。后来发现居然还真有这个题：POJ 3420。4*n的递推方程为：<br>　　　　f[n] = f[n-1] + 4 * f[n-2] + 2 * f[n-3] + 3 * f[n-4] + 2 * f[n-5] + 3 * f[n-6] + ...<br>　　　　　　 = 5 * f[n-2] + 6 * f[n-3] + 5 * f[n-4] + 5 * f[n-5] + ...<br>　　　　　　 = 5 * f[n-2] + (5 * f[n-3] + 6 * f[n-4] + 5 * f[n-5] + ...) + f[n-3] - f[n-4]<br>　　　　　　 = 5 * f[n-2] + f[n-1] + f[n-3] - f[n-4]<br>　　后面的做法就一样了，算法复杂度(4 ^ 3 * log n)。<br><br><br><img src ="http://www.cppblog.com/sdfond/aggbug/103070.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sdfond/" target="_blank">sdfond</a> 2009-12-12 20:10 <a href="http://www.cppblog.com/sdfond/archive/2009/12/12/103070.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>POJ 2411 Mondriaan's Dream</title><link>http://www.cppblog.com/sdfond/archive/2009/07/31/91761.html</link><dc:creator>sdfond</dc:creator><author>sdfond</author><pubDate>Fri, 31 Jul 2009 00:12:00 GMT</pubDate><guid>http://www.cppblog.com/sdfond/archive/2009/07/31/91761.html</guid><wfw:comment>http://www.cppblog.com/sdfond/comments/91761.html</wfw:comment><comments>http://www.cppblog.com/sdfond/archive/2009/07/31/91761.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sdfond/comments/commentRss/91761.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sdfond/services/trackbacks/91761.html</trackback:ping><description><![CDATA[<p>这个题目去年就过了，用得是状态压缩dp，不过没用dfs预处理，当时做得不是很明白，还是参考网上的一个代码做的。<br>现在重新做了一下这个题目，请教了icecream，学会了一个很简练的做法，而且比较好理解还好写。<br>首先还是状态的表示，用0表示没有放木块，用1表示放了木块。此外，对于一个横放的木块，对应的两位都用1表示；对于一个竖放的木块，第一行用1表示，第二行用0表示。这只是一种设状态的方式，当然还有别的设法，但是这种方法在接下来就会发现优点。</p>
<p>状态表示完就要处理转移了，如何判断一个转移是否合法比较难办，用一个dfs却可以简洁的解决这个问题。<br>对于上一行到下一行的转移，规定上一行一定填满，这样有三种方式：<br>&nbsp;&nbsp;&nbsp; dfs(col + 1, (s1 &lt;&lt; 1) | 1, s2 &lt;&lt; 1, n);<br>&nbsp;&nbsp;&nbsp; dfs(col + 1, s1 &lt;&lt; 1, (s2 &lt;&lt; 1) | 1, n);<br>&nbsp;&nbsp;&nbsp; dfs(col + 2, (s1 &lt;&lt; 2) | 3, (s2 &lt;&lt; 2) | 3, n);<br>第一种上面是1，那么下面一定是0，表示是一个竖放的木块。<br>第二种上面是0，就是说这个位置一定是一个竖放木块的下半截，那么下一行肯定是要另起一行了，放一个竖放或者横放的木块都必须是1。<br>第三种相当于上下两行各放一个横木块。<br>实现的时候我用了一个vector记录每个状态所有可行的转移，这样在dp的时候可以加快一些效率。</p>
<p>还有一个问题需要考虑，那就是初值和最终的结果。如果寻找合法状态，依然比较麻烦，假设共有n行，可以分别在这n行上下新加两行。下面一行都是1，由于第n行肯定要填满，这样新加的全1的行就相当于顶住了第n行使其没有凸出（有凸出那么第n+1行有0），而通过第n行到第n+1行转移保留了所有合法状态；同理最上面加的那行保证第一行没有凸出。最后第n+1行对应全1的状态就是最终的结果了。通过新加行巧妙地解决了初值和终值。</p>
<p>实现的时候也需要注意一下，在TSP问题中，外层循环是状态，内层是点，之所以这样写因为在枚举点的时候，可能会从比当前编号大的点转移，但是由于无论怎样转移过来的状态肯定比当前状态小（去掉了1），所以先从小到大枚举状态就保证转移过来的状态一定是算过的。而这个题目里面正好反过来，因为状态可能从比当前状态大的状态转移过来，而行数肯定是从编号小的行转移，因此先枚举行就能保证转移过来的状态一定是更新过的。</p>
<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">cstdio</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br>#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">vector</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br>#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">algorithm</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">namespace</span><span style="COLOR: #000000">&nbsp;std;<br></span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;N&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">11</span><span style="COLOR: #000000">;<br><br>vector</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;g[</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">N];<br></span><span style="COLOR: #0000ff">long</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">long</span><span style="COLOR: #000000">&nbsp;dp[N</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">][</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">N];<br><br></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;dfs(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;col,&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;s1,&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;s2,&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;n)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(col&nbsp;</span><span style="COLOR: #000000">&gt;=</span><span style="COLOR: #000000">&nbsp;n)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(s1&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;n)&nbsp;</span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000">&nbsp;s2&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;n))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g[s2].push_back(s1);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;dfs(col&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,&nbsp;(s1&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #000000">|</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,&nbsp;s2&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,&nbsp;n);<br>&nbsp;&nbsp;&nbsp;&nbsp;dfs(col&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,&nbsp;s1&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,&nbsp;(s2&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #000000">|</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,&nbsp;n);<br>&nbsp;&nbsp;&nbsp;&nbsp;dfs(col&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,&nbsp;(s1&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #000000">|</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,&nbsp;(s2&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #000000">|</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,&nbsp;n);<br>}<br></span><span style="COLOR: #0000ff">long</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">long</span><span style="COLOR: #000000">&nbsp;calc(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;m,&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;n)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(m&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">&nbsp;n)&nbsp;&nbsp;swap(m,&nbsp;n);<br>&nbsp;&nbsp;&nbsp;&nbsp;dfs(</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,&nbsp;n);<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;state&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;n;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;dp[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">][</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">]&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;i&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;&nbsp;i&nbsp;</span><span style="COLOR: #000000">&lt;=</span><span style="COLOR: #000000">&nbsp;m&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;&nbsp;i</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;s&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;&nbsp;s&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">&nbsp;state;&nbsp;s</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;j&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;&nbsp;j&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">&nbsp;g[s].size();&nbsp;j</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dp[i][s]&nbsp;</span><span style="COLOR: #000000">+=</span><span style="COLOR: #000000">&nbsp;dp[i</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">][g[s][j]];<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;dp[m</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">][state</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">];<br>}<br><br></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;main()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;m,&nbsp;n;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">&nbsp;(scanf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%d&nbsp;%d</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">m,&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">n)&nbsp;</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(m&nbsp;</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000">&nbsp;n&nbsp;</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">break</span><span style="COLOR: #000000">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;i&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;&nbsp;i&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;N);&nbsp;i</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g[i].clear();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;memset(dp,&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #0000ff">sizeof</span><span style="COLOR: #000000">(dp));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%I64d\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;calc(m,&nbsp;n));<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br>}<br></span></div>
<img src ="http://www.cppblog.com/sdfond/aggbug/91761.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sdfond/" target="_blank">sdfond</a> 2009-07-31 08:12 <a href="http://www.cppblog.com/sdfond/archive/2009/07/31/91761.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>最大M子段和</title><link>http://www.cppblog.com/sdfond/archive/2009/06/19/88083.html</link><dc:creator>sdfond</dc:creator><author>sdfond</author><pubDate>Fri, 19 Jun 2009 03:18:00 GMT</pubDate><guid>http://www.cppblog.com/sdfond/archive/2009/06/19/88083.html</guid><wfw:comment>http://www.cppblog.com/sdfond/comments/88083.html</wfw:comment><comments>http://www.cppblog.com/sdfond/archive/2009/06/19/88083.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sdfond/comments/commentRss/88083.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sdfond/services/trackbacks/88083.html</trackback:ping><description><![CDATA[　　给定n个数求这n个数划分成互不相交的m段的最大m子段和。<br>　　经典的动态规划优化的问题。设f(i, j)表示前i个数划分成j段，且包括第i个数的最大m子段和，那么有dp方程：<br>　　　　f(i, j) = max { f(i - 1, j) + v[i], max {f(k, j - 1) + v[i]}(k = j - 1 ... i - 1) }<br>　　也就是说第i个数要么自己划到第j段，要么和前一个数一起划到第j段里面，转移是O(n)的，总复杂度O(n * n * m)。<br>　　可以引入一个辅助数组来优化转移。设g(i, j)表示前i个数划分成j段的最大子段和（注意第i个数未必在j段里面），那么递推关系如下：<br>　　　　g(i, j) = max{g(i - 1, j), f(i, j)}，分是否加入第i个数来转移<br>　　这样f的递推关系就变成：<br>　　　　f(i, j) = max{f(i - 1, j), g(i - 1, j - 1)} + v[i]，转移变成了O(1)<br>　　这样最后的结果就是g[n][m]，通过引入辅助数组巧妙的优化了转移。实现的时候可以用一维数组，速度很快。<br><br>附HDU 1024题目代码：<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">cstdio</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br>#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">algorithm</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">namespace</span><span style="COLOR: #000000">&nbsp;std;<br></span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;N&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1000010</span><span style="COLOR: #000000">,&nbsp;INF&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0x3fffffff</span><span style="COLOR: #000000">;<br><br></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;f[N],&nbsp;g[N],&nbsp;a[N];<br><br></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;max_sum(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;m,&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;n)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;i,&nbsp;j,&nbsp;t;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;(i&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;&nbsp;i&nbsp;</span><span style="COLOR: #000000">&lt;=</span><span style="COLOR: #000000">&nbsp;n;&nbsp;i</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;min(i,&nbsp;m);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;(j&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;&nbsp;j&nbsp;</span><span style="COLOR: #000000">&lt;=</span><span style="COLOR: #000000">&nbsp;t;&nbsp;j</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f[j]&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;max(f[j],&nbsp;g[j</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">])&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;a[i];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g[j</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">]&nbsp;</span><span style="COLOR: #000000">&gt;?=</span><span style="COLOR: #000000">&nbsp;f[j</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g[j</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">]&nbsp;</span><span style="COLOR: #000000">&gt;?=</span><span style="COLOR: #000000">&nbsp;f[j</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">];<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;g[m];<br>}<br><br></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;main()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;m,&nbsp;n;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">&nbsp;(scanf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%d&nbsp;%d</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">m,&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">n)&nbsp;</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000">&nbsp;m&nbsp;</span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000">&nbsp;n)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;i&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;&nbsp;i&nbsp;</span><span style="COLOR: #000000">&lt;=</span><span style="COLOR: #000000">&nbsp;n;&nbsp;i</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f[i]&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;g[i]&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">INF;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scanf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%d</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">a[i]);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%d\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;max_sum(m,&nbsp;n));<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br>}<br></span></div>
<img src ="http://www.cppblog.com/sdfond/aggbug/88083.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sdfond/" target="_blank">sdfond</a> 2009-06-19 11:18 <a href="http://www.cppblog.com/sdfond/archive/2009/06/19/88083.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>USACO 3.4 Raucous Rockers</title><link>http://www.cppblog.com/sdfond/archive/2009/03/10/76118.html</link><dc:creator>sdfond</dc:creator><author>sdfond</author><pubDate>Tue, 10 Mar 2009 07:31:00 GMT</pubDate><guid>http://www.cppblog.com/sdfond/archive/2009/03/10/76118.html</guid><wfw:comment>http://www.cppblog.com/sdfond/comments/76118.html</wfw:comment><comments>http://www.cppblog.com/sdfond/archive/2009/03/10/76118.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sdfond/comments/commentRss/76118.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sdfond/services/trackbacks/76118.html</trackback:ping><description><![CDATA[终于通了第三章。<br><br>这个题目我设的三维状态，dp[i][j][k]表示前i个歌曲放在前j个唱片中第j个唱片用了k分钟的最大歌曲数。<br>转移方程：dp[i][j][k] = max{ dp[i-1][j][k-w[i]] + 1, dp[i-1][j][k], dp[i-1][j-1][p] }&nbsp; p = 0...t<br>跟背包问题差不多，就是加了一个唱片个数和容量的限制。三维状态一维转移，时间复杂度 O(n * m * t * t)<br><br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: #008000">/*</span><span style="COLOR: #008000"><br>ID:&nbsp;shyprom1<br>PROG:&nbsp;rockers<br>LANG:&nbsp;C++<br></span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br>#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">cstdio</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><br></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;main()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;freopen(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">rockers.in</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">r</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;stdin);<br>&nbsp;&nbsp;&nbsp;&nbsp;freopen(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">rockers.out</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">w</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;stdout);<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;N&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">32</span><span style="COLOR: #000000">;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;n,&nbsp;m,&nbsp;t,&nbsp;v,&nbsp;dp[N][N]&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;{</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">},&nbsp;ans&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;scanf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%d&nbsp;%d&nbsp;%d</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">n,&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">t,&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">m);<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;i&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;&nbsp;i&nbsp;</span><span style="COLOR: #000000">&lt;=</span><span style="COLOR: #000000">&nbsp;n;&nbsp;i</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scanf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%d</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">v);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;j&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;&nbsp;j&nbsp;</span><span style="COLOR: #000000">&lt;=</span><span style="COLOR: #000000">&nbsp;m;&nbsp;j</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;k&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;t;&nbsp;k&nbsp;</span><span style="COLOR: #000000">&gt;=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;&nbsp;k</span><span style="COLOR: #000000">--</span><span style="COLOR: #000000">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;p&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;&nbsp;p&nbsp;</span><span style="COLOR: #000000">&lt;=</span><span style="COLOR: #000000">&nbsp;t;&nbsp;p</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dp[j][k]&nbsp;</span><span style="COLOR: #000000">&gt;?=</span><span style="COLOR: #000000">&nbsp;dp[j</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">][p];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(k&nbsp;</span><span style="COLOR: #000000">&gt;=</span><span style="COLOR: #000000">&nbsp;v)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dp[j][k]&nbsp;</span><span style="COLOR: #000000">&gt;?=</span><span style="COLOR: #000000">&nbsp;dp[j][k</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">v]&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;i&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;&nbsp;i&nbsp;</span><span style="COLOR: #000000">&lt;=</span><span style="COLOR: #000000">&nbsp;t;&nbsp;i</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ans&nbsp;</span><span style="COLOR: #000000">&gt;?=</span><span style="COLOR: #000000">&nbsp;dp[m][i];<br>&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%d\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;ans);<br><br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br>}<br></span></div>
<br>
<img src ="http://www.cppblog.com/sdfond/aggbug/76118.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sdfond/" target="_blank">sdfond</a> 2009-03-10 15:31 <a href="http://www.cppblog.com/sdfond/archive/2009/03/10/76118.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>