标签:递归 Knockout Tournament dfs int vector maxn ans id
K - Knockout Tournament 递归,暴力求解
题目大意:
这个题目大意有点难说明,还是自己理解的好。
如果n=10,那么就是比赛一定是上面的图的形式。
题解:
先读懂题目大意,找到一个合理的递归方式,然后暴力求每一个可能,往上回传一个vector数组。
思维不大,主要题目要看懂!
#include <bits/stdc++.h>
using namespace std;
#define PI acos(-1)
const int maxn = 5e3+10;
typedef long long ll;
double p[maxn];
ll a[maxn];
struct node{
int id;
double p;
node(int id=0,double p=0):id(id),p(p){}
};
void print(vector<node> ans){
int len = ans.size();
for(int i=0;i<len;i++) printf("id = %d p = %f\n", ans[i].id,ans[i].p);
}
int m;
int id[maxn],cnt;
vector<node> dfs(int rt){
if((rt<<1)>m){
++cnt;
vector<node> a;a.clear();
a.push_back(node(cnt,1));
return a;
}
vector<node>lc = dfs(rt<<1);
vector<node>rc = dfs(rt<<1|1);
int Llen = lc.size(),Rlen = rc.size();
vector<node>ans;
ans.clear();
for(int i=0;i<Llen;i++){
double sum = 0;
int u = lc[i].id;
// printf("u = %d\n", u);
for(int j=0;j<Rlen;j++){
int v = rc[j].id;
sum += 1.0*a[u]/(1.0*(a[u]+a[v]))*lc[i].p*rc[j].p;
}
ans.push_back(node(u,sum));
}
for(int i=0;i<Rlen;i++){
double sum = 0;
int u = rc[i].id;
for(int j=0;j<Llen;j++){
int v = lc[j].id;
sum += 1.0*a[u]/(1.0*(a[u]+a[v]))*rc[i].p*lc[j].p;
}
ans.push_back(node(u,sum));
}
// printf("rt = %d\n", rt);
// print(ans);
return ans;
}
vector<node>ans;
bool cmp(int a,int b){
return a>b;
}
int main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%lld",&a[n-i+1]);
sort(a+1,a+n,cmp);
m = 2*n - 1;
ans = dfs(1);
int len = ans.size();
for(int i=0;i<len;i++){
if(ans[i].id==n){
printf("%.10f\n", ans[i].p);
}
}
return 0;
}
标签:递归,Knockout,Tournament,dfs,int,vector,maxn,ans,id 来源: https://www.cnblogs.com/EchoZQN/p/13768435.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。