【Codeforces 678E】Another Sith Tournament &【JZOJ 4648】锦标赛

来源:互联网 发布:文章校对软件 编辑:程序博客网 时间:2024/05/16 09:08

Description

Codeforces

The rules of Sith Tournament are well known to everyone. n Sith take part in the Tournament. The Tournament starts with the random choice of two Sith who will fight in the first battle. As one of them loses, his place is taken by the next randomly chosen Sith who didn’t fight before. Does it need to be said that each battle in the Sith Tournament ends with a death of one of opponents? The Tournament ends when the only Sith remains alive.

Jedi Ivan accidentally appeared in the list of the participants in the Sith Tournament. However, his skills in the Light Side of the Force are so strong so he can influence the choice of participants either who start the Tournament or who take the loser’s place after each battle. Of course, he won’t miss his chance to take advantage of it. Help him to calculate the probability of his victory.

JZOJ

403机房最近决定举行一场锦标赛。锦标赛共有N个人参加,共进行N-1轮。第一轮随机挑选两名选手进行决斗,胜者进入下一轮的比赛,第二轮到第N-1轮再每轮随机挑选1名选手与上一轮胜利的选手决斗,最后只剩一轮选手。第i名选手与第j名选手决斗,第i名选手胜利的概率是a[i][j].
作为一号选手的富榄想知道如何安排每轮出场的选手可以使得他获胜的概率最大,并求出这个最大概率。

抽象题意:有n个人要两两对决(n-1)场,已知每两个人对决的胜率,求一安排顺序,使1的最大胜率,输出最大的胜率。

Solution

拿到题就可以得出此题肯定是状态压缩DP,而DP方式有很多种:
1. 从活到死;
2. 从死到活;
而我们发现,从活到死,还要考虑每个人的胜率,很恶心,所有我们放过来考虑:从死到活,
设DP:f[I][j],I表示压缩的状态,j表示当前谁赢,
当全场只剩下富榄时,他的胜率为1,
DP式显然:

fI,i=max(fI,j,fI2i,jaj,i+fI2j,iai,j)
(保证i,j在I中)
复杂度:O(2nn2)

Code

#include<iostream>#include<cstdio> #include<cstdlib>#define fo(i,a,b) for(int i=a;i<=b;i++)using namespace std;typedef double db;const int N=25;int read(int &n){    char ch=' ';int q=0,w=1;    for(;(ch!='-')&&((ch<'0')||(ch>'9'));ch=getchar());    if(ch=='-')w=-1,ch=getchar();    for(;ch>='0' && ch<='9';ch=getchar())q=q*10+ch-48;n=q*w;return n;}int n;int b[N],b1[N];db a[N][N],f[N][(1<<19)+10],ans;int er[N];void ss(int q,int w,int e){    if(q>n)    {        fo(i,1,n)if((er[i]&e))            fo(j,1,n)if((er[j]&(e-er[i])))            {                f[i][e]=max(f[i][e],f[i][e-er[j]]*a[i][j]+f[j][e-er[i]]*a[j][i]);            }        return;    }    if(q+w<=n)ss(q+1,w,e);    if(w)ss(q+1,w-1,e+er[q]);}int main(){    er[1]=1;fo(i,2,N-1)er[i]=er[i-1]<<1;    int q,w;    read(n);    fo(i,1,n)fo(j,1,n)scanf("%lf",&a[i][j]);    f[1][1]=1;    fo(i,2,n)ss(1,i,0);    ans=0;    fo(i,1,n)        ans=max(ans,f[i][er[n+1]-1]);    printf("%.7lf\n",ans);    return 0;}
0 0