洛谷P3802:小魔女帕琪

时间:2022-09-15 08:11:50

题目背景

从前有一个聪明的小魔女帕琪,兴趣是狩猎吸血鬼。

帕琪能熟练使用七种属性(金、木、水、火、土、日、月)的魔法,除了能使用这么多种属性魔法外,她还能将两种以上属性组合,从而唱出强力的魔法。比如说为了加强攻击力而将火和木组合,为了掩盖弱点而将火和土组合等等,变化非常丰富。

题目描述

现在帕琪与强大的夜之女王,吸血鬼蕾咪相遇了,夜之女王蕾咪具有非常强大的生命力,普通的魔法难以造成效果,只有终极魔法:帕琪七重奏才能对蕾咪造成伤害。帕琪七重奏的触发条件是:连续释放的7个魔法中,如果魔法的属性各不相同,就能触发一次帕琪七重奏。

现在帕琪有7种属性的能量晶体,分别为a1,a2,a3,a4,a5,a6,a7(均为自然数),每次释放魔法时,会随机消耗一个现有的能量晶体,然后释放一个对应属性的魔法。

现在帕琪想知道,她释放出帕琪七重奏的期望次数是多少,可是她并不会算,于是找到了学OI的你

输入输出格式

输入格式:

一行7个数字,a1,a2,a3,a4,a5,a6,a7

输出格式:

一个四舍五入保留3位的浮点数

人话题意:7种魔法,每种数量不一定,求最多可以有多少个长度为7的全部不同子序列

题解:

一道数学题...然而我居然看了半天没看懂题解,我真是太弱啦!

七种可能比较难考虑 我们从两种开始

假设将题里的7换成2 并且已知第一种为2,第二种为1

不妨设填数的时候是按顺序填,那么根据组合数学的知识,我们显然可以看出

填第一个数时填到的几率显然是2/(2+1)

第二个数填的几率当然是1/(2+1-1)

这里2+1-1 表示的是sigma(ai)-1,想一想是挺显然的 因为实际上只是由于前面填了k个数(当然这个例子里k=1)

因为每个事件是独立的 根据乘法原理 概率显然是他们的乘积

但我们忽略了一个问题 实际上这7种魔法可以任意组合 于是需要在结果前乘上一个7的阶乘

于是我们就可以得到表达式

设n=sigma(ai),可以表示为7!*a1/n*a2/n-1*a3/n-2*......*a6/n-5*a7/n-6

但这就结束了吗?

你以为结束了 其实没结束哒!

注意到我们是枚举第i端区间的开头 也就是说有n-6端完整的区间 而在n-6之后已经无法以i为开头成为一个长度为7的区间了

因此需要在答案上乘上一个n-6

发现恰好可以约掉 那么答案就是7!*a1/n*a2/n-1*a3/n-2*......*a6/n-5*a7...

———————————————我是萌萌哒分割线—————————————————————————————

很难想象这是一道分类为普及/提高-的题......

我真是太弱啦!

#pragma GCC optimize("O2")
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<limits.h>
#include<ctime>
#define N 100001
typedef long long ll;
const int inf=0x3fffffff;
const int maxn=2017;
using namespace std;
inline int read()
{
int f=1,x=0;char ch=getchar();
while(ch>'9'|ch<'0')
{
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch<='9'&&ch>='0')
{
x=(x<<3)+(x<<1)+ch-'0';
ch=getchar();
}
return f*x;
}
double a[N],b[N],ans,sum=1;
int main()
{
for(int i=1;i<=7;i++)
{
a[i]=read();
ans+=a[i];
sum*=i;
}
printf("%.3f",sum*a[1]*a[2]*a[3]*a[4]*a[5]*a[6]*a[7]/(ans*(ans-1)*(ans-2)*(ans-3)*(ans-4)*(ans-5)));
}