bzoj4584: [Apio2016]赛艇
2016-05-13 18:28
316 查看
根据题意可想到离散化后dp:dp[i][j][k]表示前i个数在区间j内放k个的方案数,开滚动复杂度O(n^3)。然而被bzoj卡常。。。(约1.8s)优化之后变得更慢了。。
看了AC代码,发现可以换种思路:
看了AC代码,发现可以换种思路:
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #define N 505 #define ll long long #define MO 1000000007 using namespace std; int n,m,a ,b ,S[N*2],sum ,dp[N*2] ,inv ,C[N*2] ; ll Ans; int main() { scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d%d",&a[i],&b[i]),S[i*2-1]=a[i],S[i*2]=b[i]+1; sort(S+1,S+n*2+1);m=1; for (int i=2;i<=n*2;i++) if (S[i]!=S[i-1]) S[++m]=S[i]; inv[1]=1; for (int i=2;i<=n;i++) inv[i]=(ll)(MO-MO/i)*inv[MO%i]%MO; for (int i=1;i<m;i++) { C[i][0]=1; for (int j=1;j<=n;j++) C[i][j]=(ll)C[i][j-1]*(S[i+1]-S[i]+j-1)%MO*inv[j]%MO; } for (int i=1;i<m;i++)//DP[i][j]:前j个到达i的方案数 { dp[i-1][0]=1; for (int j=1;j<=n;j++) { sum[j]=sum[j-1]; dp[i][j]=dp[i-1][j]; if (a[j]<=S[i]&&S[i+1]-1<=b[j]) { sum[j]++; for (int k=0;k<j;k++) dp[i][j]=(dp[i][j]+(ll)dp[i-1][k]*C[i][sum[j]-sum[k]])%MO; } } } for (int i=1;i<=n;i++) Ans=Ans+dp[m-1][i]; printf("%lld\n",Ans%MO); return 0; }复杂度O(n^3),约0.6s。
相关文章推荐
- 限制input输入类型(多种方法实现)
- 使用 comment-net-ftp-3.5.jar 实现FTPClient时遇到的listFiles()返回空的问题小结
- java 异常 throw 和 throws 的区别
- 区间DP--凸多边形三角剖分
- Make递归调用之参数传递
- 再谈HashMap-由一个实际问题引发的对HashMap设计吐嘈
- SpringMVC Controller 介绍
- mongo的学习
- Oracle11gR2下搭建DataGuard主备同步详解
- python 学习笔记12(序列常用方法总结)
- String.matches()的用法/正则表达式
- unity3d中让物体显示和隐藏的方法
- struts文件上传下载
- The Quantum L3 router and floating IPs
- ios移动端直播
- 你是想读书,还是想读完书?
- 学习进度表
- 关于编程的时候使用自动化.
- Codeforces Round #101 (Div. 2) B. Hopscotch
- 项目完成了,如何做项目的总结会议?