14030: 【原4030】cfcome
题目
题目描述
author: Kodak 原OJ链接:https://acm.sjtu.edu.cn/OnlineJudge-old/problem/4030
Description
日天最近入坑了一个隔膜叫cfcome,因为一直打不过wtz还充钱开了svip
vip可以让日天知道自己每一枪开出去打中wtz的概率,svip在此基础上增加了伤害,不再每枪造成1点伤害,而是连续击中的第K枪造成2K-1点伤害,如果没击中则重新开始计数
然而日天还是只会见面把弹夹打空,他想知道有没有可能打赢wtz,所以需要计算自己对wtz的期望伤害
Input Format
第一行一个数N,N <= 1e6, 日天弹夹里剩余子弹数。
之后一行N个用空格分开的实数ai, (0<=ai<=1), 每一枪打中wtz的几率
Output Format
一个数,日天对wtz的期望伤害,保留六位小数
Sample Input
3
0.5 0.5 0.5
Sample Output
2.750000
Pangbo13's solution
/*
一道数学题
*/
#include<iostream>
using namespace std;
int main(){
double damage = 0;
double last_hit_pro = 0,last_damage_avg = 0;
double this_hit_pro = 0,this_damage_avg = 0;
int n;
scanf("%d",&n);
for(int i = 0;i<n;i++){
scanf("%lf",&this_hit_pro);
this_damage_avg = (last_damage_avg+2 * last_hit_pro) * this_hit_pro + (1-last_hit_pro) * this_hit_pro;
last_hit_pro = this_hit_pro;
last_damage_avg = this_damage_avg;
damage += this_damage_avg;
}
printf("%f",damage);
}
q4x3's solution
/**
* dp
* f[i]表示第i颗子弹对答案的贡献
* 状态转移方程:
* f[i] = ((1 - a[i - 1]) + a[i - 1] * (f[i - 1] / a[i - 1] + 2)) * a[i]
* 化简
* 注意输出格式
**/
#include <iostream>
#include <iomanip>
using namespace std;
int N;
double a[100233], f[100233], ans;
int main() {
cin >> N;
for(int i = 1;i <= N;++ i)
cin >> a[i];
f[1] = a[1];
ans = a[1];
for(int i = 2;i <= N;++ i) {
f[i] = (1 + f[i - 1] + a[i - 1]) * a[i];
ans += f[i];
}
cout << fixed << setprecision(6) << ans << endl;
}
victrid's solution
#include <iomanip>
#include <iostream>
using namespace std;
int main() {
int N;
cin >> N;
double* P = new double[N + 1];
//single shot
double* Eh = new double[N + 1];
double* E = new double[N + 1];
for (int i = 1; i <= N; i++) {
cin >> P[i];
}
P[0] = 0;
E[0] = 0;
Eh[0] = 0;
for (int i = 1; i <= N; i++) {
Eh[i] = (Eh[i - 1] + 1) * P[i - 1] + 1;
E[i] = E[i - 1] + Eh[i] * P[i];
}
cout << setiosflags(ios::fixed) << setprecision(6) << E[N];
return 0;
}
zqy2018's solution
#include <bits/stdc++.h>
using namespace std;
int main(){
int n;
scanf("%d", &n);
if (!n) {
printf("%.6lf\n", 0.0);
return 0;
}
double sum1 = 0, sum2 = 0, ans = 0, lst = 0;
for (int i = 1; i <= n; ++i){
double p;
scanf("%lf", &p);
sum1 += 2 * sum2, sum1 += (1 - lst), sum1 *= p;
ans += sum1;
sum2 += (1 - lst), sum2 *= p;
lst = p;
}
printf("%.6lf\n", ans);
return 0;
}