【BZOJ4559】【JLOI2016】—成绩比较(拉格朗日插值+dp)
傳送門
dpdpdp
f[i][j]f[i][j]f[i][j]表示前iii門課,有jjj個人沒有被碾壓的方案數
考慮f[i?1][j]f[i-1][j]f[i?1][j]轉移到f[i][w](j≤w)f[i][w](j\le w)f[i][w](j≤w)
首先要選出w?jw-jw?j個新的沒被他碾壓的人
由于之前已經有一些沒被碾壓的人,所以方案數為(n?i+1w?j){n-i+1\choose w-j}(w?jn?i+1?)
還有Ri?1?w+jR_i-1-w+jRi??1?w+j個人是本來就沒有被碾壓的,從原來沒被碾壓得人中選,方案數為(Ri?1?w+jj){R_i-1-w+j\choose j}(jRi??1?w+j?)
這些人組成了排名比他高的
再考慮每一課內,枚舉當前分數xxx,則有(U?x)R?1?xn?R(U-x)^{R-1}*x^{n-R}(U?x)R?1?xn?R種情況
令g(i)=∑x=1Ui(Ui?x)Ri?1?xn?Rig(i)=\sum_{x=1}^{U_i}(U_i-x)^{R_i-1}*x^{n-R_i}g(i)=∑x=1Ui??(Ui??x)Ri??1?xn?Ri?
則dpdpdp轉移:f[i][w]=g(i)(n?i+1w?j)(Ri?1?w+jj)f[i?1][j]f[i][w]=g(i){n-i+1\choose w-j}{R_i-1-w+j\choose j}f[i-1][j]f[i][w]=g(i)(w?jn?i+1?)(jRi??1?w+j?)f[i?1][j]
但是UUU太大,無法直接枚舉
考慮∑x=1U(U?x)R?1\sum_{x=1}^{U}(U-x)^{R-1}∑x=1U?(U?x)R?1可以看做關于UUU的RRR次方多項式
也就是不超過nnn次多項式
拉格朗日插值就可以了
復雜度O(n3)O(n^3)O(n3)
#include<bits/stdc++.h> using namespace std; const int RLEN=1<<21|1; inline char gc(){static char ibuf[RLEN],*ib,*ob;(ib==ob)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));return (ib==ob)?EOF:*ib++; } #define gc getchar inline int read(){char ch=gc();int res=0,f=1;while(!isdigit(ch))f^=ch=='-',ch=gc();while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();return f?res:-res; } #define ll long long #define pii pair<int,int> #define fi first #define se second #define pb push_back #define pob pop_back #define pf push_front #define pof pop_front #define mp make_pair #define bg begin #define re register const int mod=1e9+7,g=3; inline int add(int a,int b){return a+b>=mod?a+b-mod:a+b;} inline void Add(int &a,int b){a=a+b>=mod?a+b-mod:a+b;} inline int dec(int a,int b){return a>=b?a-b:a-b+mod;} inline void Dec(int &a,int b){a=a>=b?a-b:a-b+mod;} inline int mul(int a,int b){return 1ll*a*b>=mod?1ll*a*b%mod:a*b;} inline void Mul(int &a,int b){a=mul(a,b);} inline int ksm(int a,int b,int res=1){for(;b;b>>=1,Mul(a,a))(b&1)&&(Mul(res,a),1);return res;} inline void chemx(int &a,int b){a>b?0:a=b;} inline void chemn(int &a,int b){a<b?a=b:0;} const int N=105; int u[N],r[N],fac[N],pf[N][N],n,m,k,f[N][N]; int c[N][N]; inline void init(){for(int i=0;i<N;i++){c[i][0]=c[i][i]=1;for(int j=1;j<i;j++)c[i][j]=add(c[i-1][j],c[i-1][j-1]);}pf[0][0]=1;for(int i=1;i<N;i++){pf[i][0]=1,pf[i][1]=i;for(int j=2;j<N;j++)pf[i][j]=mul(pf[i][j-1],i);}fac[0]=1;for(int i=1;i<N;i++)fac[i]=mul(fac[i-1],i); } inline int calc(int u,int r){static int y[N];memset(y,0,sizeof(y));for(int i=1;i<=n+1;i++){for(int j=1;j<=i;j++)Add(y[i],mul(pf[i-j][r-1],pf[j][n-r]));if(i==u)return y[i];}int res=0;for(int i=1;i<=n+1;i++){int tmp=mul(fac[i-1],fac[n-i+1]);Mul(tmp,dec(u,i));if((n-i+1)&1)Mul(tmp,dec(0,1));tmp=ksm(tmp,mod-2),Mul(tmp,y[i]),Add(res,tmp);}for(int i=1;i<=n+1;i++)Mul(res,dec(u,i));return res; } inline int C(int i,int j){return (i<0||j<0||i<j)?0:c[i][j]; } int main(){init();n=read(),m=read(),k=read();for(int i=1;i<=m;i++)u[i]=read();for(int i=1;i<=m;i++)r[i]=read();f[0][0]=1;for(int i=1;i<=m;i++){int g=calc(u[i],r[i]);for(int j=0;j<=n;j++)for(int k=j;k<=n;k++)Add(f[i][k],mul(mul(g,f[i-1][j]),mul(C(j,r[i]-1-k+j),C(n-j-1,k-j))));}cout<<f[m][n-k-1]; }轉載于:https://www.cnblogs.com/stargazer-cyk/p/11145532.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的【BZOJ4559】【JLOI2016】—成绩比较(拉格朗日插值+dp)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ROS系统中的多个版本Boost问题
- 下一篇: 结构体指针需要申请指针内存,结构体对象不