牛客网练习赛26B(简单的dp)
题目链接:https://www.nowcoder.com/acm/contest/180/B
链接:https://www.nowcoder.com/acm/contest/180/B
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
Special Judge, 64bit IO Format: %lld
空间限制:C/C++ 262144K,其他语言524288K
Special Judge, 64bit IO Format: %lld
题目描述
小a有个烟花,每个烟花代表着互不相同的颜色,对于第个烟花,它有的概率点燃,现在小a要去点燃它们,他想知道产生颜色的期望个数 及 产生恰好产生种颜色的概率
输入描述:
第一行两个整数
接下来一行
个数,第
个数
表示第
个烟花被点燃的概率
输出描述:
输出有两行
第一行表示产生不同颜色的期望个数
第二行表示产生恰好种颜色的概率
以换行符分割
备注:
对于
的数据:
对于
的数据:
输出均保留4位小数,若你的答案误差与std不超过
即为正确
具体思路看代码
#include<iostream> #include<string.h> #include<map> #include<cstdio> #include<cstring> #include<stdio.h> #include<cmath> #include<ctype.h> #include<math.h> #include<algorithm> #include<set> #include<queue> typedef long long ll; using namespace std; const ll mod=1e9+7; const int maxn=1e5+10; const int maxk=5e3+10; const int maxx=1e4+10; const ll maxe=1000+10; #define INF 0x3f3f3f3f3f3f #define Lson l,mid,rt<<1 #define Rson mid+1,r,rt<<1|1 double a[maxn],b[2][maxn];//b[i][j]代表前i个烟花,选了j个的概率,需要用到滚动数组,因为n的范围太大,开二维会爆 int main() { double sum=0; int n,k,p=0; scanf("%d%d",&n,&k); //cin>>n>>k; for(int i=1;i<=n;i++) { cin>>a[i]; sum+=a[i]; } b[0][0]=1-a[1]; b[0][1]=a[1]; for(int i=2;i<=n;i++) { p^=1; for(int j=0;j<=min(i,k);j++) { if(j==0) { b[p][j]=b[p^1][j]*(1-a[i]); } else { b[p][j]=b[p^1][j-1]*a[i]+b[p^1][j]*(1-a[i]);//前i-1个选了j个则当前的不选,前i-1个选了j-1个,则当前的选 } } } printf("%.4lf\n",sum); printf("%.4lf\n",b[p][k]); }
当初的梦想实现了吗,事到如今只好放弃吗~