今天洛谷比赛的题。(打不了CF只好做洛谷比赛,用空气树这个号打的)
A的非常莫名。
题目链接:https://www.luogu.com.cn/problem/P2051
首先要能计算出期望值,我完全没有学过期望,只好乱猜。
期望值应该是要按最坏的打算。
要求一次性成功,否则重来。
那么期望第一个任务做的次数便是所有概率乘积的倒数。
那么第二个任务呢?就是\(2\)~\(n\)所有概率乘积的倒数。
以此类推。也就是后缀了。
而我当时完全想错了。
但是直觉认为是贪心,排序。
于是推了个这样的式子。(根据题,\(p[i]都*了10000\))
\(xx.x\)表示完成代价,\(xx.y\)表示期望值\(p[i]\),\(10000/xx.y\)也就是单独一个任务的期望次数
排序的式子(也就是把xx放在yy前的要求):
\(10000 * xx.x/xx.y+10000 * 10000 * yy.x/xx.y/yy.y<10000 * yy.x/yy.y+10000 * 10000 * xx.x/yy.y/xx.y;\)
\(-->xx.x * yy.y+10000 * yy.x<yy.x * xx.y+10000 * xx.x\)
然后\(WA\)了。
于是我开始乱猜,把\(<改>\)就过了!!惊讶万分。
什么原因?
显然,我当时的思路是按照前缀,而实际是按期望值的后缀。也就是我排出的是反着的。
式子应该是:
\(10000 * 10000 * xx.x/xx.y/yy.y+10000 * yy.x/yy.y<10000 * 10000 * yy.x/yy.y/xx.x+10000 * xx.x/xx.y\)
\(-->10000 * xx.x+yy.x * xx.y<10000 * yy.x+xx.x * yy.y\)
所以,我当时刚好相反了(想成了前缀,也就是把序列颠倒),把\(<改>\)就过了。
附上当时的代码。
#include<cstdio> #include<iostream> #include<cmath> #include<algorithm> #include<cstring> #include<queue> #include<map> #include<bitset> #include<vector> using namespace std; #define int long long #define re register int inline int read(){ int x=0,ff=1;char c=getchar(); while(c<'0'||c>'9'){if(c=='-')ff=-1;c=getchar();} while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();} return x*ff; } struct tt{ int x,y,id; bool friend operator <(tt xx,tt yy){ return xx.x*yy.y+10000*yy.x>yy.x*xx.y+10000*xx.x; } }a[500005]; int n; inline void debug(int &x){cout<<x<<endl;} signed main(){ n=read();bool is=1; for(re i=1;i<=n;i++)a[i].x=read(),a[i].id=i; for(re i=1;i<=n;i++)a[i].y=read(),is&=a[i].y>0; if(!is){puts("Impossible");return 0;} sort(a+1,a+n+1); for(re i=1;i<=n;i++)printf("%lld ",a[i].id); puts(""); return 0; }
所以这就算我自己摸索出期望了?
来源:https://www.cnblogs.com/ffrxy01bt/p/12244108.html