403機房最近決定舉行一場錦標賽。錦標賽共有n個人參加,共進行n-1輪。第一輪隨機挑選兩名選手進行決鬥,勝者進入下一輪的比賽,第二輪到第n-1輪再每輪隨機挑選1名選手與上一輪勝利的選手決鬥,最後只剩一輪選手。第i名選手與第j名選手決鬥,第i名選手勝利的概率是a[i][j].
作為一號選手的富欖想知道如何安排每輪出場的選手可以使得他獲勝的概率最大,並求出這個最大概率。
一開始打了乙個水dp,還以為是對的,結果只有10分tat。
不過n≤18,這種題看起來就像狀壓dp。
正常我們可以想到f[i][j]表示在i這個狀態,上一輪挑戰j勝利了的概率。
然後f[i][j]可以推到f[i-1<<(k-1)][j]或f[i-1<<(j-1)][k]不過直接這樣推,更新狀態的次數比較多,時間不夠。
我們再想想,因為1號選手一定要贏,所以可以從死推到活,那麼初始化f[1][1]=1,
那麼對於f[i][j]顯然也是用f[i-1<<(k-1)][j]和f[i-1<<(j-1)][k]來推出,因為這兩個狀態都可以推到f[i][j]所以得出dp式 f[
i][j
]=ma
x(f[
i][j
],f[
i−2k
−1][
j]∗a
[j][
k]+f
[i−2
j−1]
[k]∗
a[k]
[j])
為什麼這樣可以呢,比如從x推到y的概率為a[x][y],x同時推到z的概率為a[x][z],那麼因為y和z都是x發生後才會產生,那麼必須y和z產生了人乙個就會產生x,所以概率要加起來。
#include
#include
#include
#include
#include
#define fo(i,a,b) for(i=a;i<=b;i++)
using
namespace
std;
typedef
double db;
const
int maxn=20;
int i,j,k,l,t,n,m;
db a[maxn][maxn],ans,f[1
<<19][maxn];
int main()}}
fo(i,1,n)ans=max(ans,f[(1
<1][i]);
printf("%.7f\n",ans);
}
錦標賽 NOIP2016提高A組模擬7 17
403機房最近決定舉行一場錦標賽。錦標賽共有n個人參加,共進行n 1輪。第一輪隨機挑選兩名選手進行決鬥,勝者進入下一輪的比賽,第二輪到第n 1輪再每輪隨機挑選1名選手與上一輪勝利的選手決鬥,最後只剩一輪選手。第i名選手與第j名選手決鬥,第i名選手勝利的概率是a i j 作為一號選手的富欖想知道如何安...
錦標賽問題 遞迴
設有n位選手參加網球迴圈賽,n 2 k,迴圈賽共進行n 1天,每位選手要與其他n 1位選手比賽一場,且每位選手每天比賽一場,不能輪空,按一下要求為比賽安排日程,1 每位選手必須與其他n 1格選手格賽一場 2 每個選手每天只能賽一場 3 迴圈賽一共進行n 1天 請按此要求將比賽日程表設計成有n行和n ...
牛客 錦標賽
組委會正在為美團點評codem大賽的決賽設計新賽制。比賽有 n 個人參加 其中 n 為2的冪 每個參賽者根據資格賽和預賽 複賽的成績,會有不同的積分。比賽採取錦標賽賽制,分輪次進行,設某一輪有 m個人參加,那麼參賽者會被分為 m 2 組,每組恰好 2 人,m 2組的人分別廝殺。我們假定積分高的人肯定...