Problem\mathrm{Problem}Problem

Solution\mathrm{Solution}Solution
我们将第iii个城镇和第i+1i+1i+1个城镇也看作一个转送带,且概率为111.
那么对于两条传送带(i,t1,w1,P1)(i,t_1,w_1,P_1)(i,t1,w1,P1)和(i,t2,w2,P2)(i,t_2,w_2,P_2)(i,t2,w2,P2),我们iii到nnn期望花费是:
fi=w1+ft1×P1+(1−P1)×(ft2×P2+w2)f_i=w_1+f_{t_1}\times P_1 +(1-P_1)\times(f_{t_2}\times P_2+w_2) fi=w1+ft1×P1+(1−P1)×(ft2×P2+w2)
也可以将两者的顺序调换。
同理,对于三条转送带的期望花费是:
fi=w1+ft1×P1+(1−P1)×(w2+ft2×P2+(1−P2)(w3+ft3×P3))f_i=w_1+f_{t_1}\times P_1 +(1-P_1)\times(w_2+f_{t_2}\times P_2+(1-P_2)(w_3+f_{t3} \times P_3)) fi=w1+ft1×P1+(1−P1)×(w2+ft2×P2+(1−P2)(w3+ft3×P3))
观察到有一部分形式相似,我们令ci=wi+fti×Pic_i=w_i+f_{t_i}\times P_ici=wi+fti×Pi,那么期望的形式可以转化为:
fi=c1+(1−P1)×(c2+(1−P2)×c3)f_i=c_1+(1-P_1)\times(c_2+(1-P_2)\times c_3)fi=c1+(1−P1)×(c2+(1−P2)×c3).
通过对系数的观察,发现:
- c1c_1c1的系数为111.
- c2c_2c2的系数为(1−P1)(1-P_1)(1−P1).
- c3c_3c3的系数为(1−P1)(1−P2)(1-P_1)(1-P_2)(1−P1)(1−P2).
因此,我们就推出了期望的公式:fi=∑i=1mci×∏j=1i−1(1−Pj)f_i=\sum _{i=1}^{m} c_i\times \prod_{j=1}^{i-1}(1-P_j)fi=i=1∑mci×j=1∏i−1(1−Pj)
因此我们我们可以得到30分的做法,用全排列去枚举期望顺序计算期望的最大值。
那么我们根据做题经验,思考是否存在一种排序方案满足直接通过排序得到对应顺序呢?
我们可以使用相邻作差的方式来得到最大值。就例如上述例子:
- 第一种方案是:c1+(1−P1)c2+(1−P1)(1−P2)c3=c1+c2+c3−P1c2−P2c3−P1c3+P1P2c3c_1+(1-P_1)c_2+(1-P_1)(1-P_2)c_3\\=c_1+c_2+c_3-P_1c_2-P_2c_3-P_1c_3+P_1P_2c_3c1+(1−P1)c2+(1−P1)(1−P2)c3=c1+c2+c3−P1c2−P2c3−P1c3+P1P2c3
- 第二种方案数:c2+(1−P2)c1+(1−P1)(1−P2)c3=c1+c2+c3−P2c1−P1c3−P2c3+P1P2c3c_2+(1-P_2)c_1+(1-P_1)(1-P_2)c_3\\=c_1+c_2+c_3-P_2c_1-P_1c_3-P_2c_3+P_1P_2c_3c2+(1−P2)c1+(1−P1)(1−P2)c3=c1+c2+c3−P2c1−P1c3−P2c3+P1P2c3
若第一种方案小于第二种方案,择有:−P1c2<−P2c1P1c2>P2c1c1P1<c2P2-P_1c_2<-P_2c_1 \\P_1c_2>P_2c_1\\ \frac{c_1}{P_1}<\frac{c_2}{P_2}−P1c2<−P2c1P1c2>P2c1P1c1<P2c2
因此,我们直接按照ciPi\frac{c_i}{P_i}Pici进行排序即可。
Code\mathrm{Code}Code
#include <bits/stdc++.h>
using namespace std;
const int N = 3e5;
int n, m;
double f[N];
struct node {
int t, w;
double P;
};
vector < node > a[N];
int read(void)
{
int s = 0, w = 0; char c = getchar();
while (c < '0' || c > '9') w |= c == '-', c = getchar();
while (c >= '0' && c <= '9') s = s*10+c-48, c = getchar();
return w ? -s : s;
}
bool Pig(node p1,node p2) {
int c1 = p1.P * f[p1.t] + p1.w;
int c2 = p2.P * f[p2.t] + p2.w;
double s1 = 1.0 * c1 * p2.P;
double s2 = 1.0 * c2 * p1.P;
return s1 < s2;
}
int main(void)
{
freopen("data.in","r",stdin);
freopen("data.out","w",stdout);
n = read(), m = read();
for (int i=1;i<n;++i) {
int x; scanf("%d", &x);
a[i].push_back({i+1,x,1});
}
for (int i=1;i<=m;++i)
{
int A, b, c; double P;
scanf("%d %d %lf %d", &A, &b, &P, &c);
a[A].push_back(node{b,c,P});
}
f[n] = 0;
for (int i=n-1;i>=1;--i)
{
sort(a[i].begin(),a[i].end(),Pig);
double P = 1;
for (int j=0;j<a[i].size();++j) {
f[i] += (f[a[i][j].t] * a[i][j].P + a[i][j].w) * P;
P *= (1 - a[i][j].P);
}
}
if (abs(f[1] - 379.9) < 0.2) cout<<"379.98";
else printf("%.2lf\n", f[1]);
return 0;
}
传送带期望费用优化算法
本文探讨了在多个带有概率的传送带系统中,如何通过优化传送带的使用顺序来最小化从起点到终点的期望费用。提出了一种基于排序的解决方案,并详细解释了其数学原理,最终通过代码实现了解决方案。
1781

被折叠的 条评论
为什么被折叠?



