2019雅礼集训 D7T1 inverse [概率/期望,DP]

题目描述:

样例:

input1:
3 1
1 2 3

output1:
833333340

input2:
5 10
2 4 1 3 5

output2:
62258360

数据范围与约定:



概率/期望的常用套路:将许许多多个元素单独考虑,以达到解决问题的目的。

这里发现不可能整个序列一起考虑,于是枚举任意两个位置,计算出k次翻转之后左边大于右边的概率,再加起来就好了。

于是我们有了一个非常暴力的DP:

令\(dp(i,j,k)?\) 表示k次翻转之后i位置大于j位置的概率。为了方便我们强行令\(i>j?\)

然后,对于上一次发生的几种可能的区间翻转分别考虑:

一、\(r<i\; ||\; l>j\; ||\; i<l \leq r<j\)

我们发现这种情况时i和j没有受到影响,于是直接继承上一个时间的状态即可。

贡献:\[({{i-1}\choose 2}+{{n-j}\choose 2}+{{j-i-1}\choose 2})dp(i,j,k-1)\]

二、\(l \leq i \leq r < j?\)

此时i在上一次的位置是\(l+r-i\),j没有发生变化。

贡献:\(\sum_{l=1}^i \sum_{r=i}^{j-1} dp(l+r-i,j,k-1)\)

三、\(i<l \leq j \leq r?\)

此时j在上一次的位置是\(l+r-j\),i没有变化。

贡献:\(\sum_{l=i+1}^j \sum_{r=j}^n dp(i,l+r-j,k-1)\)

四、\(l \leq i < j \leq r\)

此时i、j的位置都发生了变化,上一次分别是\(l+r-i\),\(l+r-j\)。

贡献:\(\sum_{l=1}^i \sum_{r=j}^n (1-dp(l+r-j,l+r-i,k-1))=i(n-j+1)\sum_{l=1}^i \sum_{r=j}^n dp(l+r-j,l+r-i,k-1)\)

将上面四种贡献加起来,再除个\(\frac{n(n+1)}{2}?\)就好了。

复杂度\(O(n^4k)\),显然要挂。

考虑优化:发现转移方程可以用前缀和优化一下,这里以第二种情况为例:

\[
S_1(n,j,k)=\sum_{i=1}^n dp(i,j,k),S_2(n,j,k)=\sum_{i=1}^n S_2(i,j,k) \\sum_{l=1}^i \sum_{r=i}^{j-1} dp(l+r-i,j,k-1) \=\sum_{l=1}^i(S_1(l+j-i-1)-S_1(l-1,j,k-1))\=S_2(j-1,j,k-1)-S_2(j-i-1,j,k-1)-S_2(i-1,j,k-1)
\]

可以\(O(1)\)求啦!

同理可得,

\[
S_3(i,n,k)=\sum_{j=1}^n dp(i,j,k),S_4(i,n,k)=\sum_{j=1}^n S_3(i,j,k)\第三种情况:S_4(i,n,k-1)-S_4(i,n+i-j,k-1)-S_4(i,j-1,k-1)\g(i,j,k)=dp(i,i+j,k-1),S_5(n,j,k)=\sum_{i=1}^n g(i,j,k),S_6(n,j,k)=\sum_{i=1}^n S_5(i,j,k)\第四种情况:i(n-j+1)-S_6(n+i-j,j-i,k-1)+S_6(n-j,j-i,k-1)+S_6(i-1,j-i,k-1)
\]

大功告成!

最后,由于出题人卡常(1s),你可能需要一些常数优化才能过(滑稽)

代码:

#include<cstdio>

namespace my_std{
    const int mod=1e9+7;
    #define rep(i,x,y) for (register int i=(x);i<=(y);++i)
    #define drep(i,x,y) for (register int i=(x);i>=(y);--i)
    #define sz 510
    typedef long long ll;
    template<typename T>
    inline void read(T& t)
    {
        t=0;char ch=getchar();
        while(ch>‘9‘||ch<‘0‘) ch=getchar();
        while(ch<=‘9‘&&ch>=‘0‘) t=t*10+ch-48,ch=getchar();
    }
    void file(){freopen("a.txt","r",stdin);}
}
using namespace my_std;

inline ll ksm(ll x,int y)
{
    ll ret=1;
    for (;y;y>>=1,x=x*x%mod) if (y&1) ret=ret*x%mod;
    return ret;
}

int n,K;
int a[sz];

ll dp[51][sz][sz];

ll s1[51][sz][sz],s2[51][sz][sz],s3[51][sz][sz];

ll C[sz];

inline void M(ll &x){if (x>=mod) x-=mod;}

int main()
{
    file();
    read(n),read(K);
    rep(i,1,n) read(a[i]);
    rep(i,1,n)
        rep(j,i+1,n)
            dp[0][i][j]=(a[i]>a[j]);
    rep(i,1,n) C[i]=C[i-1]+i;
    ll INV=ksm(C[n],mod-2);
    rep(t,0,K-1)
    {
        rep(j,1,n)
        {
            rep(i,1,j-1) s1[t][i][j]=s1[t][i-1][j]+dp[t][i][j];
            rep(i,1,j-1) M(s1[t][i][j]+=s1[t][i-1][j]);
        }
        rep(i,1,n)
        {
            rep(j,i+1,n) s2[t][i][j]=s2[t][i][j-1]+dp[t][i][j];
            rep(j,i+1,n) M(s2[t][i][j]+=s2[t][i][j-1]);
        }
        rep(j,0,n-1)
        {
            rep(i,1,n-j) s3[t][i][j]=s3[t][i-1][j]+dp[t][i][i+j];
            rep(i,1,n-j) M(s3[t][i][j]+=s3[t][i-1][j]);
        }

        rep(i,1,n) rep(j,i+1,n)
        {
            ll &S=dp[t+1][i][j];

            S=(C[i-1]+C[n-j]+C[j-i-1])*dp[t][i][j];

            S+=s1[t][j-1][j]-s1[t][j-i-1][j]-s1[t][i-1][j];

            S+=s2[t][i][n]-s2[t][i][n+i-j]-s2[t][i][j-1]+s2[t][i][i-1];

            S-=s3[t][n+i-j][j-i]-s3[t][n-j][j-i]-s3[t][i-1][j-i];

            S+=i*(n-j+1);

            S=(S%mod+mod)%mod*INV%mod;

//          dp[t+1][i][j]=(C(i-1)+C(n-j)+C(j-i-1))*dp[t][i][j];
//          rep(l,1,i) rep(r,i,j-1) dp[t+1][i][j]+=dp[t][l+r-i][j];
//          rep(l,i+1,j) rep(r,j,n) dp[t+1][i][j]+=dp[t][i][l+r-j];
//          rep(l,1,i) rep(r,j,n) dp[t+1][i][j]+=1-dp[t][l+r-j][l+r-i];
//          dp[t+1][i][j]/=C(n);
        }
    }

    ll ans=0;
    rep(i,1,n)
        rep(j,i+1,n)
            M(ans+=dp[K][i][j]);

    ans=(ans%mod+mod)%mod;

    printf("%lld",ans);
}

原文地址:https://www.cnblogs.com/p-b-p-b/p/10260907.html

时间: 2024-10-20 23:48:34

2019雅礼集训 D7T1 inverse [概率/期望,DP]的相关文章

2019雅礼集训 D4T1 w [费用流]

题目描述: 样例: input1: 4 1 2 1 2 3 4 1 2 1 3 3 4 1 2 2 3 1 4 2 1 3 4 1 1 2 3 output1: 9 input2: 5 1 1 3 99 99 100 2 1 2 1 3 3 4 3 5 1 3 1 2 2 4 2 5 2 1 2 3 1 2 1 2 2 1 output2: 198 数据范围: 先放个原题地址:CF1061E. 毒瘤出题人搬原题差评 毒瘤出题人题目翻译出锅差评 这题看到如此不伦不类的问法,似乎不是dp.贪心等算法

【2019雅礼集训】【第一类斯特林数】【NTT&amp;多项式】permutation

目录 题意 输入格式 输出格式 思路: 代码 题意 找有多少个长度为n的排列,使得从左往右数,有a个元素比之前的所有数字都大,从右往左数,有b个元素比之后的所有数字都大. n<=2*10^5,a,b<=n 输入格式 输入三个整数n,a,b. 输出格式 输出一个整数,表示答案. 思路: 这道题是真的神啊... 首先,根据官方题解的思路,首先有一个n^2的DP: 定义dp[i][j]表示一个长度为i的排列,从前往后数一共有j个数字大于所有排在它前面的数字. 首先有转移式: \[dp[i][j]=d

2019雅礼集训 D7T2 subsequence [DP,平衡树]

题目描述: 样例: input1: 5 -2 -8 0 5 -3 output1: 5 10 13 2 -13 input2: 6 -10 20 -30 40 -50 60 output2: 60 160 280 390 400 210 数据范围与约定: 考虑DP:令\(dp(i,j)\)表示前\(i\)个点选\(j\)个,能得到的最大价值. 得到转移方程:\(dp(i,j)=\max\{dp(i-1,j),dp(i-1,j-1)+a_i\cdot j\}\) 这个方程很明显是\(n^2\)的.

2019雅礼集训 D10T2 硬币翻转 [交互题]

题目描述: coin.h: #include<string> void guess(); int ask(std::string coin); grader.cpp: #include "coin.h" #include <iostream> #include <assert.h> using namespace std; namespace U { using u64 = unsigned long long; using i64 = long l

2019雅礼集训 D10T1 数字重排 [DP]

题目描述: 样例: input: 5 5 5 10 17 23 output: 3 数据范围与约定: 简单DP,不做解释,直接搬题解. 标程: #include<bits/stdc++.h> using namespace std; const int N=1e5+5; int n,a[N],m,s; bitset<N>f,g; int main(){ freopen("sort.in","r",stdin); freopen("s

#6030. 【雅礼集训 2017 Day1】矩阵

#6030. 「雅礼集训 2017 Day1」矩阵 题目描述 有一个 n×n  的矩阵,每个位置 (i,j) 如果是 . 表示为白色,如果是 # 表示为黑色. 初始时,每个位置可以是黑色或白色的,(i,j)  位置的值会作为 ai,j 给你. 现在有一种操作,选择两个整数 i,j∈[1,n],记 (i,1),(i,2),…,(i,n) (i, 1), (i, 2)的颜色为 C1,C2,…Cn ??,将 (1,j),(2,j),…,(n,j)  的颜色赋为 C1,C2,…,Cn ??. 你的任务是

【BZOJ-1419】Red is good 概率期望DP

1419: Red is good Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 660  Solved: 257[Submit][Status][Discuss] Description 桌面上有R张红牌和B张黑牌,随机打乱顺序后放在桌面上,开始一张一张地翻牌,翻到红牌得到1美元,黑牌则付出1美元.可以随时停止翻牌,在最优策略下平均能得到多少钱. Input 一行输入两个数R,B,其值在0到5000之间 Output 在最优策略下平均能得到多少钱

CF148D--Bag of mice+概率期望dp

第一道概率期望dp:) 其实和一般的dp也差不多,只要状态选好就行了. 定义dp[i][j]表示还剩i只白老鼠j只黑老鼠时候公主赢得概率. 则:1.公主选白老鼠,直接赢,概率:i/(i+j) 2.公主选黑老鼠 1)龙选黑老鼠,逃走黑老鼠:概率:j/(i+j)*(j-1)/(i+j-1)*(j-2)/(i+j-2) 2)  龙选黑老鼠,逃走白老鼠:概率:j/(i+j)*(j-1)/(i+j-1)*i/(i+j-2) 3) 龙选白老鼠,这样公主是必输的,不用考虑 然后dp[i][j]等于以上概率之和

Codeforces - 1264C - Beautiful Mirrors with queries - 概率期望dp

一道挺难的概率期望dp,花了很长时间才学会div2的E怎么做,但这道题是另一种设法. https://codeforces.com/contest/1264/problem/C 要设为 \(dp_i\) 表示第 \(i\) 个格子期望经过多少次,所以 \(dp_{n+1}=1\). https://www.cnblogs.com/suncongbo/p/11996219.html 原文地址:https://www.cnblogs.com/KisekiPurin2019/p/12063633.ht