1樓:王贇 Maigo
匿名使用者的動態規劃解法是正解,不過直接看程式不容易看懂,我來用人話解釋一遍。
首先澄清一點題意:從題主的描述來看,相同的數交換位置算同一種擺法。不過從匿名使用者的程式來看,題目是以撲克牌為背景的,點數相同的牌還有花色的區別。我就按後一種題意來講了。
先來設計一種樸素的狀態:用表示還剩下張1、張2、……、張n需要擺放。
考慮到不允許相同的數字相鄰,還需要在狀態中補充乙個數k,表示第一張牌不能是k點(以下稱k為「禁手」)。
這樣,乙個狀態對應的擺法數就是:
0}} a_i \cdot C(a_1, a_2, \cdots, a_i - 1, \cdots, a_n, i)" eeimg="1"/>
這裡的下標i就列舉了第一張牌是幾點,它不能取k,也不能取已經一張不剩的牌。第一張牌選了i點後,下一張牌的「禁手」就變成i了。
動態規劃的初始條件是(禁手是幾都無所謂),
而待求的擺法數是(0表示無禁手)。
這種狀態設計方法能夠解決問題,但明顯有大量的冗餘狀態:
把狀態中的各個交換(若涉及禁手,則也要做相應調整),擺法數是一樣的。
其實,狀態中每種牌還剩幾張並不重要,重要的是有幾種牌還剩1張、有幾種牌還剩2張……等等。
所以我們把狀態修改成這樣:用表示還有種牌剩餘1張,種牌剩餘2張,……,種牌剩餘m張,禁手牌剩餘k張。m取各的最大值就夠了。
這樣,狀態轉移方程就變成了:
\delta_}} (b_i - \delta_) \cdot i \cdot C(b_1, b_2, \cdots, b_ + 1, b_i - 1, \cdots, b_m, i-1) " eeimg="1"/>
這裡下標i表示選擇一種還剩i張的牌。定義在i=k時取1,否則取0。求和式中的第一項表示有種牌可選(若禁手牌恰也剩餘i張,則少一種);第二項i表示每種牌有i張不同花色可選;第三項是轉移後的狀態——剩餘i張的牌少了一種,而剩餘i-1張的牌多了一種,同時禁手牌(即剛剛選的牌)剩餘i-1張。
初始條件是仍是,待求狀態無禁手。
在實際程式設計的時候,為了保證僅計算有用的狀態,可以用記憶化搜尋實現。
若不計不同花色的區別,只需去掉第乙個狀態轉移方程右邊的,或第二個狀態轉移方程右邊的i。
2樓:
程式設計之美那個題可以用dp來做。
#include
#include
using
namespace
std;
unsigned
long
longdp[
14][
14][
14][
14][5];
bool
cal[
14][
14][
14][
14][5];
// b[x] 表示的是還有b[x]種牌還剩x張, forbid表示的禁手牌還剩下的數量
unsigned
long
long
get_dp
(int(&
b)[5],
intforbid
)// 標記為計算過
Cal=
true
;// Dp初始為0Dp=
0;// 記錄是否還有牌
bool
hascard
=false
;// 新的計數
intnewb[5
];// 列舉相同面值剩餘數目是 i
for(
inti=1
;i<=4;
i++)// 如果沒卡,應該特殊處理為1,初始狀態if(!hascard
)returnDp;
}int
main
()elseif(
p=='T')
elseif(
p=='J')
elseif(
p=='Q')
elseif(
p=='K')
else
cin>>p;
}int
newb[5
];memset
(newb,0
,sizeof
(newb
));for
(inti=
0;i<13;
i++)cout
<<"Case #"
< ": " < (newb,0 )< Ryan Lee 貼兩個老鏈結,雖然提的這個問題是原問題的子問題,但分析裡也解釋的很清楚了。 sniperelite 一種方法當然是首先弄乙個數池,池中有1 n的數字,然後每次以等概率選出乙個並從池中移除。另外MATLAB的randperm提供了乙個巧妙的思路 隨機產生n個均勻分布的隨機數,並且依次... 水牛 你是要自動在AutoCAD裡排迴路相序吧。個人覺得,搞這麼複雜沒必要吧。因為一方面,雖然程式設計可以根據輸入的計算電流給出優化的相序組合方案,但這樣子的結果肯定是相序無規律的,配電箱中就會出現一排開關所接相序完全混亂無規律的現象,對配電箱的生產和檢修都不利。而一般情況下,配電箱都是按A,B,C... 圖1.停留在棋盤上的棋子誰多誰贏。圍棋勝負規則,非常簡單,只是有時候聽起來很難。最核心的思想 最後停留在棋盤上的棋子誰多誰贏。如圖1,數一數,黑棋比白棋多,黑棋贏。圖2.無需走到填滿棋盤 後來,人們發現,填滿棋盤太蠢了,其實圍到雙方棋子都接觸,剩下的空點,對方走進去一定會被吃掉時,這些所圍空點也是我...乙個重新排列的演算法,如何計算每種排列的概率?
如何用程式語言實現三相配平計算?
圍棋普遍的判定勝負的方法是什麼?如何計算目數?