[考试反思]数学专题测试4:深度

高斯消元专题测试

联赛后第一次爆零???我也不知道发生了什么

感觉和放假的关系不大啊。。。

虽说题比平时难而且数据范围出了一点锅,但是爆零有点过了??

一眼看T3,MatrixTree啊肯定的,然后想到之前做的那个不等式的那道题直觉是容斥。

结果又想到了那个专题里幻想乡的那道题,于是更加笃定是容斥,结果思路就阻塞了。

20分的部分分好像很难写,就往后放了放,结果最后并没有时间写。

然后看起来比较简单的是T2,直到看到数据范围之前我都认为应该不会太难。

基础式子都会写,然后组合数忘记特判不合法的0了,于是把10分送掉了,可能也是因为用不习惯键盘打的时候着急了?

剩下的部分分完全看不出来它想让我干什么。。。只是因为数据范围少给了一个条件

考试的时候差点就在群里问这题是不是无解了。。。数据范围毫无破绽,如果s=1e18,m=1e9,其余为0,那么这就显然不可做了。

我还以为是我too naive于是就没有问。。。谁知道它就真的出锅了。

然而skyh猜测数据范围拿到了60分。。。猜测数据范围。。。学到了,也许吧。。。

其实最开始想到了这档部分分的打法,挺显然的,但是数据范围里没说,就没写呗。。。

看了眼T1,想起之前做的某道猜拳的题,期望dp呗。这道题要的是相对胜率更大呗,那就这么写呗

写了一半发现不是很对,虽说感觉能骗一点分但是能拿多少我也不知道。还多测,乱写可能就爆零了。

于是求稳,转向30分的部分分,大型分类讨论。

结果一直写到考试结束,没写完,交了,只有第一档部分分写了。

然后测试点又锅了没有第一档的部分分。

所以,就莫名其妙的爆零了?

嗯,就这么爆零了。

考试结束后没几分钟就涨了20分,,为何如此弱智。

T1:猜拳游戏

大意:猜拳,一回合n场,其中A决策固定(出的概率已知),赢的场多者赢得回合。A领先m2回合或B领先m1回合时取胜。求B最优决策时胜率。

$n \le 1000,m1,m2 \le 100$

比较明显的是,对于不同回合的相同局面采取的决策一定相同(局面是指已进行场数及本回合分差)。

平局的回合没有影响,但是对决策转移很碍事,考虑如何去掉。

平局了就再来一局呗,所以平局的那部分概率可以按比例分给双方。如果原来胜率为p败率是q那么在实际赢得一局的概率$\frac{p}{p+q}$

化简一下$\frac{p}{q+p}=\frac{1}{\frac{q}{p}+1}$。所以我们现在的目的就是最大化$\frac{q}{p}$

然后是一个比较经典的01分数规划思路,二分答案观察是否合法,所以现在设二分值为mid。

那么你可以认为,赢一回合积1分,输一回合扣mid分,平局不变,是否存在最优决策使总积分为正。

这个直接当成普通的期望dp倒着做回去就行了。

设$dp[i][j]$表示目前在第$i$场,已经净胜$j$场(可负)的最优积分。转移就是在石头剪刀布三种决策里取最大积分。

初状态就是$dp[n+1][x>0]=1,dp[n+1][0]=0,dp[n+1][x<0]=-mid$。答案就是$dp[1][0]$

然后我们求出了最大单回合胜率,问题在于净胜场达到$m1/m2$了。

画出转移图,点数不多,直接高斯消元解就可以。

居然卡记搜的常数弄成T40我还以为我写错了,差评

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,m1,m2;double p[4][1001],K,P,A[202][202],dp[1002][2006];
 4 unordered_map<int,double>M[1111];
 5 #define f(a,x) p[a][r]*dp[r+1][v+x]
 6 double sch(){
 7     for(int i=0;i<=n;++i)dp[n+1][i]=-K;for(int i=n+2;i<=n+n+2;++i)dp[n+1][i]=1;dp[n+1][n+1]=0;
 8     for(int r=n;~r;--r)for(int v=n+n+1;v;--v)dp[r][v]=max(max(f(1,0)+f(2,-1)+f(3,1),f(1,1)+f(2,0)+f(3,-1)),f(1,-1)+f(2,1)+f(3,0));
 9     return dp[1][n+1];
10 }
11 void Gauss(int n){
12     for(int i=0;i<=n;++i){
13         int np=i;
14         for(int j=i+1;j<=n;++j)if(fabs(A[j][i])>fabs(A[i][np]))np=j;swap(A[np],A[i]);
15         if(fabs(A[i][i])<1e-6)continue;
16         for(int j=n+1;j>=i;--j)A[i][j]/=A[i][i];
17         for(int j=0;j<=n;++j)if(j!=i)for(int k=n+1;k>=i;--k)A[j][k]-=A[j][i]*A[i][k];
18     }
19 }
20 int main(){
21     cin>>n>>m1>>m2;
22     if(n+m1+m2==0)return 0;
23     for(int i=1;i<=n;++i)for(int j=1;j<=3;++j)cin>>p[j][i],p[j][i]/=100;
24     double l=0,r=1e6;
25     while(K=(l+r)/2,r-l>1e-6){
26         if(sch()>0)l=K;else r=K;
27         for(int i=1;i<=n;++i)M[i].clear();
28     }
29     P=1-1/(1+K);
30     memset(A,0,sizeof A);
31     A[m2][m1+m2+1]=1;
32     for(int i=0;i<m1+m2-1;++i)A[i][i+1]=P-1;
33     for(int i=2;i<=m1+m2;++i)A[i][i-1]=-P;
34     for(int i=0;i<=m1+m2;++i)A[i][i]+=1;
35     Gauss(m1+m2);
36     printf("%.5lf\n",A[m1+m2][m1+m2+1]);
37     return main();
38 }

T2:inequ

不会。

T3:生成树

大意:无向图边有3种色,蓝边不超过b绿边不超过g的生成树数量。$n \le 40,m \le 1000$

这除了矩阵树还能是啥?问题在于怎么处理特殊限制。

然而这次并不是容斥,思维僵化了。

怎么在矩阵树里对不同种类的边加以区分?加个边权如何?(怎么想到的???)

在矩阵树里的边权可以通过变元矩阵树解决啊,但是这会改变生成树的数量。

为了方便我们将没有限制的红边作为基准,它的边权为1,蓝边为x绿边为y。

那么对于一个用上了a条蓝边b条绿边的生成树,它所贡献的方案树就是$x^ay^b$

而对于一种特定的边权方案我们用矩阵树定理所求出的总方案数就是$\sum\limits_{a=0}^{n-1} \sum\limits_{b=0}^{n-1} r_{a,b}x^ay^b $

其中$r_{a,b}$就是用了啊条蓝边b条绿边的生成树数量。我们要求的答案就是$\sum\limits_{i =0}^{b} \sum\limits_{j=0}^{g} r_{i,j}$

我们现在能对于给定的$x,y$用矩阵树定理求出和式的值,能计算出$x^ay^b$这个数是几,我们要求的是$r$这个系数。

而$x,y$是我们自己随便定的,所以只要我们定若干组$x,y$我们就能列出许多等式,用它们解出所有$r$的值。

其实这个过程就是插值的过程,然而二维的插值并不会,所以就草率的高斯消元将就一下就可以了。时间复杂度$O(n^6)$

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define mod 1000000007
 4 int A[44][44],B[1666][1666],n,m,a[4][44][44],lb,lc,re[44][44],cnt,X[1666],Y[1666],ans;
 5 int qp(int b,int t,int a=1){for(;t;t>>=1,b=1ll*b*b%mod)if(t&1)a=1ll*a*b%mod;return a;}
 6 int Matrix_Tree(){
 7     int a=1;
 8     for(int i=1;i<n;++i){
 9         int iv=qp(A[i][i],mod-2);a=1ll*a*A[i][i]%mod;
10         for(int j=1;j<n;++j)A[i][j]=1ll*A[i][j]*iv%mod;
11         for(int j=i+1;j<n;++j)for(int k=n-1;k>=i;--k)A[j][k]=(A[j][k]-1ll*A[j][i]*A[i][k]%mod+mod)%mod;
12     }
13     return a;
14 }
15 void Gauss(int n){
16     for(int i=1;i<=n;++i){
17         if(!B[i][i])for(int j=i+1;j<=n;++j)if(B[j][i]){swap(B[i],B[j]);break;}
18         int iv=qp(B[i][i],mod-2);
19         for(int j=1;j<=n+1;++j)B[i][j]=1ll*B[i][j]*iv%mod;
20         for(int j=1;j<=n;++j)if(i!=j)for(int k=n+1;k>=i;--k)B[j][k]=(B[j][k]-1ll*B[j][i]*B[i][k]%mod+mod)%mod;
21     }
22 }
23 int main(){
24     cin>>n>>m>>lb>>lc;
25     for(int i=1,x,y,k;i<=m;++i)cin>>x>>y>>k,a[k][x][x]++,a[k][y][y]++,a[k][x][y]--,a[k][y][x]--;
26     for(int x=0;x<n;++x)for(int y=0;x+y<n;++y)re[x][y]=++cnt,X[cnt]=x,Y[cnt]=y;
27     for(int x=0;x<n;++x)for(int y=0;x+y<n;++y){
28         for(int p=1;p<=cnt;++p)B[re[x][y]][p]=1ll*qp(x,X[p])*qp(y,Y[p])%mod;
29         for(int p=1;p<=n;++p)for(int q=1;q<=n;++q)A[p][q]=(a[1][p][q]+1ll*a[2][p][q]*x+1ll*a[3][p][q]*y)%mod;
30         B[re[x][y]][cnt+1]=Matrix_Tree();
31     }Gauss(cnt);
32     for(int x=0;x<=lb;++x)for(int y=0;y<=lc;++y)ans=(ans+B[re[x][y]][cnt+1])%mod;
33     cout<<ans<<endl;
34 }

原文地址:https://www.cnblogs.com/hzoi-DeepinC/p/12219617.html

时间: 2024-10-13 17:15:30

[考试反思]数学专题测试4:深度的相关文章

[考试反思]图论专题测试:怀疑

没写完,但是好像有人需要代码,于是先发布出来. 回去之后记得贴排行榜. 0+0+55.rk11. 考场上想出了T1的三分,不确定,没有写. 写了另一个好像靠谱点的二分,但是好像写挂了... T2没读题,又是没读题,又是没读题!!!! 没看到它要求的是简单路径,于是简单爆9. T3一眼网络流,两眼不会流,三眼状压写完就走. 最后也就T3有分.靠着一个状压苟到这个名次..? T1:center 题目大意:选择图上(点或边)上任意一点,使所有节点到这个节点最远的距离最小.$ n \le 200$ 这是

[考试反思]1002csp-s模拟测试56:凌乱

放假回来状态回升??(玩够了-但是稍困) T1打的不完全对,但是过掉了.很快的想到了二分吧喇叭啦.. 然后T2也挺快想出来了但是挂细节没发现,考试快结束的时候才发现出锅了. 改了过来是正解,但是出题人无良卡了线段树强制树状数组,T了一个子任务,卡常到飞起. T3暴力没什么问题. 卡常是一种习惯.要注意题目数据范围观察是否卡常. T1: 所有的决策都是一条一次函数. 分两类,斜率正或斜率非负. 如果第二类的直线里有在T=0时符合要求的,那么答案就是0,所以check(0)一下. 如果非负的直线都在

[考试反思]0929csp-s模拟测试55:沦陷

菜得过分. 面对T1的大板子不知所措,然后T2的贪心不小心把排序语句删了... T1这种大模板啊...其实我是觉得我能打出来的,然后先用一个小时码了一个2k. 然后做T2想贪心就出来了.十分钟码完T3暴力之后回T1打对拍瞬间爆炸. 于是又重新打了一个2k,WA0.对拍发现. 然后考试就没几分钟了交暴力走了. 不要打完就跑,记得早点对拍改进思路. T1: 的确是挺裸的线段树.离散化或者权值线段树都可以. 但是考场上两个都打出来都死了. 最后用离散化A的. 1 #include<cstdio> 2

[考试反思]1003csp-s模拟测试58:沉淀

稳住阵脚. 还可以. 至少想拿到的分都拿到了,最后一题的确因为不会按秩合并和线段树分治而想不出来. 对拍了,暴力都拍了.挺稳的. 但是其实也有波折,险些被卡内存. 如果内存使用不连续或申请的内存全部使用的话,切记计算内存,一点都不能开大. T1: 直接根号筛,拿map也能过. 遍历map直接begin和end啊... 1 #include<cstdio> 2 int Cnt[202]; 3 struct hash_map{ 4 int cnt,fir[10000020],l[6666666],

[考试反思]1010csp-s模拟测试67:摸索

嗯...所谓RP守恒? 仍然延续着好一场烂一场的规律. 虽说我也想打破这个规律,但是并不想在考烂之后打破这个规律.(因为下一场要考好???) 我也不知道我现在是什么状态,相较于前一阶段有所提升(第一鸡房的buff?) 但是明显还有提升空间.也可以看到离上面的差距有多大. (在去食堂的路上一顿爆捶捶傻skyh就能进步一名了hhh) 这场考试呢,T1正路是推式子然而我又开始疯狂打表找规律,最后得到了一个和正解没什么关系但是能拿到80分的式子. 也肝了一个小时,然后就停止在80分了. 并不是没有在化式

[考试反思]1012csp-s模拟测试70:盘旋

这套题比较烂... 上来看到T2是原题,一想上一次考试遇到原题就不换,这次应该也是,于是直接开始码,码了一半然后换题了 T1打表找规律或者推式子都不难... T2水的一匹暴力剪枝即可,但是我并不知道数据那么那么水所以还花了很多时间优化 T3神奇的大模拟,挺有意思但是考场上不可能有人能拿到20+ 所以因为题比较烂,所以我就上去了? 隔了一场之后RP守恒又恢复了? 啊啊不要乱说啊再过十几分钟就又要考一场了啊... T1:木板 具体化式子也就是个初中数学,结论就是(最大平方因子的平方根-1)<<3,

[考试反思]1022csp-s模拟测试82:奇异

这场考试的确颇为奇异. 两道结论题...(其中T1被称为送分题...) 决策不是很对.T1是一个只有一个参数的找规律,明显可以打表. 但是因为搜索不好打所以就没有打... 搜索再难打一个小时应该也可以模拟完了,不说推式子了,找规律肯定是能找到的啊. 然而我T1动都没动... T3跪在了高考组合数学上.... 只有一个参数的题大多是结论题,可以尝试打表找规律. 不要乱弃题! T1: 结论题.大规模推式子,因为只有一个参数,所以打表其实也很好做. 答案是$\frac{n^2-1}{9}$ 推式子先留

[考试反思]1025csp-s模拟测试87:生存

想起一句话 课上求生存,课下求发展 发展还好说,如何生存? 生存很困难... 没什么可抱怨的.有AK的.高分的也很多. 该说的在<Dust>里说完了,安静会吧. 这场rank43怎么追? 最大240分差,可能这一轮就完蛋了. 知道有多紧迫了吗? 上次爆个0导致追不回来直接滚出第一机房依旧令我印象深刻. OI不会给你任何一次失手的机会.CSP-S也只有6道题. 这一天下来分数上限就是360了? 再说这样的话Day2还能稳住心态吗? 省一可能都拿不到吧? 不要轻视任何一道题与任意一次考试,希望不要

[考试反思]1026csp-s模拟测试89:不公

稍垃圾.因为T1没A. 赶巧前一段时间学了杜教筛,结果因为教练放错题. 然后考场上疯狂yy,最后水到了一个AC. 其实的确挺不公平的,不少人也没学呢. 如果只算T1和T3的分数的话,那70分就是个垃圾. 还有.... 又一次盖掉自己70分... 想剪枝结果打错了. 在没有用堆跑Dijk时因为队列里的元素无序所以一个点可能被扩展多次,而有时候后扩展的状态更优,所以不能打标记continue. 其余其实还好,发挥的凑和吧.其实能yy出T2还是挺不容易的. 但是当然在正经考试里不会出现你学过别人没学过