bzoj4559 成绩比较【动态规划+拉格朗日插值法】
2017-12-12 08:39
309 查看
解题思路:
我们设f[i][j]表示前i门课,共有j个人没有被碾压的方案数,那么答案即为f[m][n−1−k]假设从f[i−1][w]转移到f[i][j](j≥w)
没被碾压的人数本应增加Ri−1人,但其中有一部分可能之前就没被碾压了。
则有t1=j−w个人是新增的人数,要从n−1−w个人中选,方案数为Ct1n−1−w
还有t2=Ri−1−t1个人是本就没被碾压的,要从w个人中选,方案数为Ct2w
例如w=100,Ri−1=5,j=102,则t1=2,t2=3
考虑第i门课的得分方案,若B神得了x分,则有Ri−1个人分数大于他,n−Ri个人分数小等于他,所以总方案数为
g(i)=∑x=1Ui(Ui−x)r−1xn−r
由于Ui很大,无法直接算,但注意到它是一个关于Ui的次数小等于n次的多项式,所以可以用拉格朗日插值法插U=1,2……n+1得到n+1个点进而算出g(i)的值。
由于Ri不同,所以对于每门课都要求一遍。
至此得到总的dp方程:
f[i][j]=g(i)∑w=0jCt1n−1−wCt2wf[i−1][w]
时间复杂度为O(n3)#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<cmath> #include<ctime> #include<queue> #include<vector> #include<set> #include<map> #define ll long long using namespace std; int getint() { int i=0,f=1;char c; for(c=getchar();(c<'0'||c>'9')&&c!='-';c=getchar()); if(c=='-')c=getchar(),f=-1; for(;c>='0'&&c<='9';c=getchar())i=(i<<3)+(i<<1)+c-'0'; return i*f; } const int N=105,p=1e9+7; int n,m,k; int U ,R ,c ,f ; int g ,inv ; int ksm(int x,int y) { x%=p;int res=1; for(;y;y>>=1,x=1ll*x*x%p) if(y&1)res=1ll*res*x%p; return res; } int Inter(int u,int r) { memset(g,0,sizeof(g)); for(int x=1;x<=n+1;x++) { for(int i=1;i<=x;i++) g[x]=(g[x]+1ll*ksm(x-i,r-1)*ksm(i,n-r)%p)%p; if(u==x)return g[x]; } for(int i=1;i<=n+1;i++) { inv[i]=1; for(int j=1;j<=n+1;j++) if(i!=j)inv[i]=(1ll*inv[i]*(i-j)%p+p)%p; inv[i]=ksm(inv[i],p-2); } int res=0; for(int i=1;i<=n+1;i++) { int tmp=1ll*inv[i]*g[i]%p; for(int j=1;j<=n+1;j++) if(i!=j)tmp=1ll*tmp*(u-j)%p; res=(res+tmp)%p; } return res; } int C(int i,int j) { if(i<0||j<0||j>i)return 0; return c[i][j]; } int main() { //freopen("lx.in","r",stdin); //freopen("lx.out","w",stdout); n=getint(),m=getint(),k=getint(); for(int i=1;i<=m;i++)U[i]=getint(); for(int i=1;i<=m;i++)R[i]=getint(); c[0][0]=1; for(int i=1;i<=n;i++) { c[i][0]=1; for(int j=1;j<=n;j++) c[i][j]=(c[i-1][j]+c[i-1][j-1])%p; } f[0][0]=1; for(int i=1;i<=m;i++) { int tmp=Inter(U[i],R[i]); for(int j=0;j<=n;j++) { for(int w=0;w<=j;w++) f[i][j]=(f[i][j]+1ll*f[i-1][w]*C(n-1-w,j-w)%p*C(w,R[i]-1-(j-w))%p*tmp%p)%p; } } cout<<f[m][n-1-k]<<'\n'; return 0; }
相关文章推荐
- bzoj4559[JLoi2016]成绩比较 容斥+拉格朗日插值法
- ●BZOJ 4559 [JLoi2016]成绩比较(容斥)
- bzoj 4559: [JLoi2016]成绩比较 dp+拉格朗日插值
- bzoj千题计划270:bzoj4559: [JLoi2016]成绩比较(拉格朗日插值)
- 【BZOJ】4559: [JLoi2016]成绩比较 计数DP+排列组合+拉格朗日插值
- ●BZOJ 4559 [JLoi2016]成绩比较
- 【BZOJ4559】成绩比较(组合计数,容斥原理)
- 【BZOJ4559】[JLoi2016]成绩比较 动态规划+容斥+组合数学
- bzoj4559【JLOI2016】成绩比较
- BZOJ 4559: [JLoi2016]成绩比较【计数dp,容斥,组合数
- [JLoi 2016] bzoj4559 成绩比较 [容斥原理]
- [bzoj4559][JLoi2016]成绩比较
- BZOJ 4559 [JLoi2016]成绩比较
- BZOJ4599[JLoi2016&LNoi2016]成绩比较(dp+拉格朗日插值)
- 动态规划(计数DP):JLOI 2016 成绩比较
- 4559: [JLoi2016]成绩比较
- 【动态规划/递推】BZOJ1806[IOI2007]- Miners
- bzoj 3233: [Ahoi2013]找硬币 动态规划
- 【BZOJ2442】修建草坪(动态规划,单调队列)
- 【BZOJ1003】【ZJOI2006】物流运输trans 最短路预处理+动态规划