DP?(数论+组合数学综合题:组合数性质+预处理+组合数取摸)
2015-09-23 22:28
316 查看
Link:http://acm.hdu.edu.cn/showproblem.php?pid=3944
Time Limit: 10000/3000 MS (Java/Others) Memory Limit: 128000/128000 K (Java/Others)
Total Submission(s): 2515 Accepted Submission(s): 782
Problem Description
Figure 1 shows the Yang Hui Triangle. We number the row from top to bottom 0,1,2,…and the column from left to right 0,1,2,….If using C(n,k) represents the number of row n, column k. The Yang Hui Triangle has a regular pattern as follows.
C(n,0)=C(n,n)=1 (n ≥ 0)
C(n,k)=C(n-1,k-1)+C(n-1,k) (0<k<n)
Write a program that calculates the minimum sum of numbers passed on a route that starts at the top and ends at row n, column k. Each step can go either straight down or diagonally down to the right like figure 2.
As the answer may be very large, you only need to output the answer mod p which is a prime.
Input
Input to the problem will consists of series of up to 100000 data sets. For each data there is a line contains three integers n, k(0<=k<=n<10^9) p(p<10^4 and p is a prime) . Input is terminated by end-of-file.
Output
For every test case, you should output "Case #C: " first, where C indicates the case number and starts at 1.Then output the minimum sum mod p.
Sample Input
Sample Output
Author
phyxnj@UESTC
Source
2011 Multi-University Training
Contest 11 - Host by UESTC
题意:给出杨辉三角数塔模型,求从顶部到第n行第k列的元素所经过的路径最小和。
编程思想:
这里用到了组合数的性质公式:C(n,k)=C(n-1,k-1)+C(n-1,k) 。由题意得到的规律:从目标点出发,每次都往左上方走,然后,走到第0列的时候就往上一直走(全为1),即最小值。故答案为C(n,k)+C(n-1,k-1)+……+C(n-k+1,1)+C(n-k,0)+C(n-k-1,0)+……C(0,0);若按得出的公式直接Lucas算,则TLE。。必须利用组合数的性质进行预处理。把C(n-k,0)写成C(n-k+1,0)(因为都是1!),这样,上面式子那一段,可以从尾到头依次合并,最终合并为C(n+1,k)。所以这里只要求一次组合数就可以了。预处理技巧:定义一个数组,所有小于10000的数的阶乘对所有小于10000的的素数进行取模,这样到lucas定理计算的时候就可以直接用了。
详见代码注释。
AC code:
DP?
Time Limit: 10000/3000 MS (Java/Others) Memory Limit: 128000/128000 K (Java/Others)Total Submission(s): 2515 Accepted Submission(s): 782
Problem Description
Figure 1 shows the Yang Hui Triangle. We number the row from top to bottom 0,1,2,…and the column from left to right 0,1,2,….If using C(n,k) represents the number of row n, column k. The Yang Hui Triangle has a regular pattern as follows.
C(n,0)=C(n,n)=1 (n ≥ 0)
C(n,k)=C(n-1,k-1)+C(n-1,k) (0<k<n)
Write a program that calculates the minimum sum of numbers passed on a route that starts at the top and ends at row n, column k. Each step can go either straight down or diagonally down to the right like figure 2.
As the answer may be very large, you only need to output the answer mod p which is a prime.
Input
Input to the problem will consists of series of up to 100000 data sets. For each data there is a line contains three integers n, k(0<=k<=n<10^9) p(p<10^4 and p is a prime) . Input is terminated by end-of-file.
Output
For every test case, you should output "Case #C: " first, where C indicates the case number and starts at 1.Then output the minimum sum mod p.
Sample Input
1 1 2 4 2 7
Sample Output
Case #1: 0 Case #2: 5
Author
phyxnj@UESTC
Source
2011 Multi-University Training
Contest 11 - Host by UESTC
题意:给出杨辉三角数塔模型,求从顶部到第n行第k列的元素所经过的路径最小和。
编程思想:
这里用到了组合数的性质公式:C(n,k)=C(n-1,k-1)+C(n-1,k) 。由题意得到的规律:从目标点出发,每次都往左上方走,然后,走到第0列的时候就往上一直走(全为1),即最小值。故答案为C(n,k)+C(n-1,k-1)+……+C(n-k+1,1)+C(n-k,0)+C(n-k-1,0)+……C(0,0);若按得出的公式直接Lucas算,则TLE。。必须利用组合数的性质进行预处理。把C(n-k,0)写成C(n-k+1,0)(因为都是1!),这样,上面式子那一段,可以从尾到头依次合并,最终合并为C(n+1,k)。所以这里只要求一次组合数就可以了。预处理技巧:定义一个数组,所有小于10000的数的阶乘对所有小于10000的的素数进行取模,这样到lucas定理计算的时候就可以直接用了。
详见代码注释。
AC code:
#include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<cmath> #include<queue> #include<map> #include<stack> #include<vector> #define LL long long #define MAXN 1000010 using namespace std; const int N=20;//模方程数 const int maxx=10005;//最大素数上限 LL a ,mod ; int frc[1300][maxx];//frc[i][j]表示(j!)%(第i个素数prim[i]) int id[maxx];//素数编号 bool vis[maxx]; int prim[maxx];//存储素数 int cnt;//素数个数 void init()//素数筛选及打表求:(j!)%(第i个素数prim[i]) { for(int i=2;i<maxx;i++) if(!vis[i]){ prim[cnt]=i; id[i]=cnt; for(int j=i*2;j<maxx;j+=i)vis[j]=1; frc[cnt][0]=1; for(int j=1;j<prim[cnt];j++) frc[cnt][j]=frc[cnt][j-1]*j%prim[cnt]; cnt++; } } /*LL mul(LL a,LL b,LL mod)//a*b%mod { LL ans=0; while(b){ if(b&1) ans=(ans+a)%mod; b>>=1; a=(a+a)%mod; } return ans; }*/ LL quick_mod(LL a,LL b,LL m)//a^b%m { LL ans=1; a%=m; while(b) { if(b&1) { ans=ans*a%m; } b>>=1; a=a*a%m; } return ans; } LL getC(LL n,LL m,int cur)//C(n,m)%mod[cur] { LL p=mod[cur];//p为要取的素数模mod[cur] if(m>n) return 0; if(m>n-m) m=n-m; LL ans=1; /* for(int i=1;i<=m;i++) { LL a=(n+i-m)%p; LL b=i%p; //ans=mul(ans,mul(a,quick_mod(b,p-2,p),p),p);//p为素数,i对p的逆元可以不用扩张欧几里得进行求解 re=i^(P-2) ans = ans * (a * quick_mod(b, p-2,p) % p) % p; }*///注释掉这个,然后用以下方法求解提高速率 //直接用打表方式求解 int num=id[p];//素数编号 ans=frc[num] *quick_mod(frc[num][n-m]*frc[num][m]%p,p-2,p)%p; return ans; } LL Lucas(LL n,LL k,int cur)//求C(n,k)%mod[cur] { LL p=mod[cur]; if(k==0) return 1%p; //return getC(n%p,k%p,cur)*Lucas(n/p,k/p,cur)%p; return getC(n % p, k % p,cur) * Lucas(n / p, k / p,cur) % p; } /*void extend_Euclid(LL a,LL b,LL &x,LL &y) { if(b==0) { x=1; y=0; return; } extend_Euclid(b,a%b,x,y); LL tmp=x; x=y; y=tmp-a/b*y; } LL CRT(LL a[],LL m[],int k)//求C(n,m)%M,其中M=(m0*m2*…*m(k-1)),mi为素数,则先用a[i]存储模方程C(n,m)%mi, { //m[]存储所有素数因子mi,k表示总共有k个模方程,返回C(n,m)%M的值 LL M=1; LL ans=0; for(int i=0;i<k;i++) M*=mod[i]; for(int i=0;i<k;i++) { LL x,y,tmp; LL Mi=M/m[i]; extend_Euclid(Mi,m[i],x,y); if(x<0) { x=-x; tmp=mul(Mi,x,M); tmp=mul(tmp,a[i],M); tmp=-tmp; } else { tmp=mul(Mi,x,M); tmp=mul(tmp,a[i],M); } ans=(ans+tmp)%M; } while(ans<0) ans+=M; return ans; }*/ int ans; int main() { //freopen("D:\\in.txt","r",stdin); int T,tempn,tempk,n,k,p; T=0; init(); while(~scanf("%d%d%d",&n,&k,&p)) { T++; if(k>n/2) { k=n-k; } mod[0]=p; ans=(Lucas(n+1,k,0)+n-k)%p; printf("Case #%d: %d\n",T,ans); } return 0; }
相关文章推荐
- 对实体--联系模型比较深入的认识
- 2015年9月23日工作日志-------------赵鑫
- 【J2EE系列】—徒手建立Web应用(HTML+Servlet+Tomcat)
- 开篇感想
- JavaScript 三种创建对象的方法
- CSS属性、BFC、IFC
- uva 1349 - Optimal Bus Route Design(完美匹配)
- HDU 5458 Stability(树链剖分 + 并查集)
- MySql数据库,对varchar类型字段str进行where str=0条件查询时,查询结果是什么
- 关于mysql添加用户和删除用户遇到的一些问题
- iOS 微信支付接入最新的完整流程
- Clarke and minecraft hdoj 5463 (数学题)
- 黑马程序员————Android中LayoutInflater布局解析的使用
- IE 兼容与CSS选择器
- 数据库
- Ubuntu忘记密码解决办法
- 对象的创建、使用及向String对象添加方法(prototype的使用)
- 如何防止文件备份到iCloud和iTunes
- libcurl.a + sqlcipher 渊源
- 0916词法分析