hdu_5794_A Simple Chess(lucas+dp)

题目链接:hdu_5794_A Simple Chess

题意:

给你n,m,从(1,1)到(n,m),每次只能从左上到右下走日字路线,有k(<=100)的不能走的位置,问你有多少方案

题解:

画图可看到路线是一个杨辉三角的图,然后我们可以将对应的x,y转换到对应的点上,也可以吧杨辉三角看成一个平行四边形,

我这里看成的平行四边形,设dp[i]为从起点到第i个障碍物的的方案数,那么dp[i]=dp[i]-sum(dp[j](第j个点能走到i这个点)*(j到i的方案数))。

然后我们把终点放到最后,最后求出的dp[end]就是答案

 1 #include<cstdio>
 2 #include<algorithm>
 3 #define F(i,a,b) for(int i=a;i<=b;i++)
 4 using namespace std;
 5 typedef long long ll;
 6 const ll P=110119;
 7 ll f[P+5],r[P+5];
 8 ll C(ll n,ll m){return n<m?0:f[n]*r[n-m]%P*r[m]%P;}
 9 ll lucas(ll n,ll m){
10     if(n<m||m<0)return 0;
11     if(!m||n==m)return 1;
12     return C(n%P,m%P)*lucas(n/P,m/P)%P;
13 }
14 void init(){
15     int i;
16     for(r[0]=r[1]=f[0]=f[1]=1,i=2;i<P;i++){
17         f[i]=f[i-1]*i%P,r[i]=-r[P%i]*(P/i)%P;
18         while(r[i]<0)r[i]+=P;
19     }
20     for(i=2;i<P;i++)r[i]=r[i]*r[i-1]%P;
21 }
22
23 ll n,m,k,ic=1,dp[110];
24
25 struct point{
26     ll x,y;
27     bool operator<(const point &b)const{return x<b.x;}
28 }p[110];
29
30 int main(){
31     init();
32     while(~scanf("%lld%lld%lld",&n,&m,&k))
33     {
34         n--,m--;
35         int fg=0;
36         F(i,1,k)
37         {
38             scanf("%lld%lld",&p[i].x,&p[i].y),p[i].x--,p[i].y--;
39             if(p[i].x==n&&p[i].y==m)fg=1;
40         }
41         printf("Case #%lld: ",ic++);
42         if(n==0&&m==0)puts("1");
43         else if((n+m)%3!=0||fg)puts("0");
44         else
45         {
46             ll x,y,tx,ty;
47             sort(p+1,p+1+k);
48             p[++k].x=n,p[k].y=m;
49             F(i,1,k)
50             {
51                 if((p[i].x+p[i].y)%3==0)
52                 {
53                     x=(p[i].x+p[i].y)/3,y=min(p[i].x,p[i].y)-x;
54                     dp[i]=lucas(x,y);
55                     F(j,1,i-1)
56                     {
57                         if(p[j].y<p[i].y&&p[j].x<p[i].x)
58                         {
59                             ll xx=p[i].x-p[j].x,yy=p[i].y-p[j].y;
60                             if((xx+yy)%3==0)
61                             {
62                                 ll tx=(xx+yy)/3,ty=min(xx,yy)-tx;
63                                 dp[i]-=(lucas(tx,ty)*dp[j])%P;
64                                 dp[i]=(dp[i]+P)%P;
65                             }
66                         }
67                     }
68                 }
69             }
70             printf("%lld\n",dp[k]);
71         }
72     }
73     return 0;
74 }

时间: 2024-11-03 21:02:34

hdu_5794_A Simple Chess(lucas+dp)的相关文章

HDU 5794 A Simple Chess (Lucas + dp)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5794 多校这题转化一下模型跟cf560E基本一样,可以先做cf上的这个题. 题目让你求一个棋子开始在(1,1),只能像马一样走且往右下方走,不经过坏点,有多少种走法能到达(n,m)点. 比如n=6, m=5 有两个坏点,模型转换 如下图: 转换成简单模型之后,只要把棋子可能经过的坏点存到结构体中,按照x与y从小到大排序. dp[i]表示从起点到第i个坏点且不经过其他坏点的方案数. dp[i] = L

hdu-5794 A Simple Chess(容斥+lucas+dp)

题目链接: A Simple Chess Time Limit: 2000/1000 MS (Java/Others)     Memory Limit: 65536/65536 K (Java/Others) Problem Description There is a n×m board, a chess want to go to the position (n,m) from the position (1,1).The chess is able to go to position (

hdu5794 A Simple Chess 容斥+Lucas 从(1,1)开始出发,每一步从(x1,y1)到达(x2,y2)满足(x2?x1)^2+(y2?y1)^2=5, x2&gt;x1,y2&gt;y1; 其实就是走日字。而且是往(n,m)方向走的日字。还有r个障碍物,障碍物不可以到达。求(1,1)到(n,m)的路径条数。

A Simple Chess Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 2597    Accepted Submission(s): 691 Problem Description There is a n×m board, a chess want to go to the position (n,m) from the pos

HDU 5794 A Simple Chess(杨辉三角+容斥原理+Lucas)

题目链接 A Simple Chess 打表发现这其实是一个杨辉三角…… 然后发现很多格子上方案数都是0 对于那写可能可以到达的点(先不考虑障碍点),我们先叫做有效的点 对于那些障碍,如果不在有效点上,则自动忽略 障碍$(A, B)$如果有效,那么就要进行如下操作: 以这个点为一个新的杨辉三角的顶点,算出目标点的坐标$(x, y)$. 目标点的答案减去$C(A, B) * C(x, y)$的值. 但是这样会造成重复计算,原因是障碍之间可能有相互影响的关系. 这个时候就要考虑容斥原理,DFS消除这

HDU 5794 A Simple Chess(卢卡斯定理 + 容斥原理)

传送门 A Simple Chess Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 667    Accepted Submission(s): 168 Problem Description There is a n×m board, a chess want to go to the position (n,m) from the

HDU 4832 Chess (DP)

Chess Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 24    Accepted Submission(s): 10 Problem Description 小度和小良最近又迷上了下棋.棋盘一共有N行M列,我们可以把左上角的格子定为(1,1),右下角的格子定为(N,M).在他们的规则中,"王"在棋盘上的走法遵循十字路线.

[ACM] hdu 4405 Aeroplane chess (概率DP)

Aeroplane chess Problem Description Hzz loves aeroplane chess very much. The chess map contains N+1 grids labeled from 0 to N. Hzz starts at grid 0. For each step he throws a dice(a dice have six faces with equal probability to face up and the number

HDU 5794:A Simple Chess(Lucas + DP)

题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5794 题意:让一个棋子从(1,1)走到(n,m),要求像马一样走日字型并只能往右下角走.里面还有r个障碍点不能经过或者到达,问有多少种走法可以走到(n,m). 思路:画个图可以发现走的点像一个斜着的杨辉三角.所以可以得到一个从点 i 走到点 j 的路径数是一个组合数. 大概就是长这样,杨辉三角的每个点的数如下. 1 1       1 1      2      1 1       3 

HDU5794 A Simple Chess 容斥+lucas

分析:转自http://blog.csdn.net/mengzhengnan/article/details/47031777 一点感想:其实这个题应该是可以想到的,但是赛场上并不会 dp[i]的定义很巧妙,容斥的思路也非常清晰 然后就是讨论lucas的用法,首先成立的条件是mod是素数 但是如果这个题mod很大,组合数取模感觉就不太可做了 我认为当mod很大时,n应该很小可以预处理,但是n很大时mod应该比较小,这样也可以预处理 如果n和mod都很大我就不会了.... 这个题在预处理的时候,同