2019杭电多校第六场
1003 Valentine’s Day
给个物品,每个物品有一个被选中的概率。任意选个物品,怎么选这个物品才能使从这个物品中选一个物品的的概率最大。
设从个物品中选中一个的概率为,那么
一开始的想法是做差,看看能不能从,但是后来发现做差的结果只能作为停止的条件,没法做决策,所以后程我换了一种推导:为了使加入后尽量大,当前的系数大于零时,就选择当前可选的最小的;反之,选择最大的。
排序预处理即可。
UPD:这题的数据比较弱,用一开始的伪算法也能ac,但是由于比赛的时候多组数据输出忘记换行了,导致一直wa…
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<stack>
#include<cstdlib>
#include <iomanip>
#define eps 1e-6
#define inf 0x3f3f3f3f
#define ll long long
#define mem(a, x) memset(a,x,sizeof(a))
typedef std::pair<ll, ll> Pll;
const int N = 1e4+10;
using namespace std;
ll gcd(ll p, ll q) { return q == 0 ? p : gcd(q, p % q); }
double p[N];
int n;
inline void init() {
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lf",&p[i]),p[i]=1-p[i];
sort(p+1,p+n+1);
}
int main() {
// ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int T;scanf("%d",&T);
while(T--){
init();
double k,res=1-p[1],exp=p[1];
double ans = res;
int l=2,r=n;
while(l<=r){
k=res-exp;
if(k>0) {
res=k*p[r]+exp;
exp*=p[r];
r--;
}
else {
res=k*p[l]+exp;
exp*=p[l];
l++;
}
ans=max(res,ans);
}
res=1-p[n];
exp=p[n];
l=1,r=n-1;
while(l<=r){
k=res-exp;
if(k>0) {
res=(res-exp)*p[r]+exp;
exp*=p[r];
r--;
}
else {
res=(res-exp)*p[l]+exp;
exp*=p[l];
l++;
}
ans=max(res,ans);
}
printf("%.12lf\n",ans);
}
return 0;
}
1009 Block Breaker
签到题,的方格,次询问,dfs即可。
浙公网安备 33010602011771号