[BZOJ 4767]两双手(组合数学+Dp)

Description

老W是个棋艺高超的棋手,他最喜欢的棋子是马,更具体地,他更加喜欢马所行走的方式。老W下棋时觉得无聊,便

决定加强马所行走的方式,更具体地,他有两双手,其中一双手能让马从(u,v)移动到(u+Ax,v+Ay)而另一双手能让

马从(u,v)移动到(u+Bx,v+By)。小W看见老W的下棋方式,觉得非常有趣,他开始思考一个问题:假设棋盘是个无限

大的二维平面,一开始马在原点(0,0)上,若用老W的两种方式进行移动,他有多少种不同的移动方法到达点(Ex,Ey

)呢?两种移动方法不同当且仅当移动步数不同或某一步所到达的点不同。老W听了这个问题,觉得还不够有趣,他

在平面上又设立了n个禁止点,表示马不能走到这些点上,现在他们想知道,这种情况下马有多少种不同的移动方

法呢?答案数可能很大,你只要告诉他们答案模(10^9+7)的值就行。

Solution

Ax*By-Ay*Bx≠0所以向量A、B的步数是固定的,走法也就有C(m+n,m)种

先对障碍点排序

Dp,f[i]表示到达障碍点i且不经过其他障碍点的方案数(用容斥减去经过其他障碍点的方案数)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define Mod 1000000007
#define MAXN 500005
typedef long long LL;
using namespace std;
int n,ax,ay,bx,by;
LL fac[MAXN],inv[MAXN],f[MAXN];
struct Node
{
    int x,y;
}p[MAXN];
void init()
{
    fac[0]=1,inv[1]=1;
    for(int i=1;i<MAXN;i++)
    fac[i]=(fac[i-1]*i)%Mod;
    for(int i=2;i<MAXN;i++)
    inv[i]=((Mod-Mod/i)*inv[Mod%i])%Mod;
    inv[0]=1;
    for(int i=1;i<=MAXN;i++)
    inv[i]=(inv[i]*inv[i-1])%Mod;
}
LL C(LL x,LL y)
{
    if(x<y)return 0;
    return ((fac[x]*inv[y])%Mod*inv[x-y])%Mod;
}
bool cmp(Node A,Node B)
{
    if(A.x==B.x)return A.y<B.y;
    return A.x<B.x;
}
void calc(int &x,int &y)
{
    int m,n;
    if((ay*x-ax*y)%(bx*ay-ax*by)){x=-1,y=-1;return;}
    n=(ay*x-ax*y)/(bx*ay-ax*by);
    if((by*x-bx*y)%(ax*by-bx*ay)){x=-1,y=-1;return;}
    m=(by*x-bx*y)/(ax*by-bx*ay);
    x=m,y=n;
}
int main()
{
    init();
    scanf("%d%d%d",&p[0].x,&p[0].y,&n);
    scanf("%d%d%d%d",&ax,&ay,&bx,&by);
    calc(p[0].x,p[0].y);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&p[i].x,&p[i].y);
        calc(p[i].x,p[i].y);
    }
    sort(p+1,p+1+n,cmp);
    p[n+1]=p[0];
    for(int i=1;i<=n+1;i++)
    {
        if(p[i].x==-1)continue;
        f[i]=C(p[i].x+p[i].y,p[i].x);
        for(int j=1;j<i;j++)
        f[i]=(f[i]-f[j]*C(p[i].x-p[j].x+p[i].y-p[j].y,p[i].x-p[j].x)%Mod+Mod)%Mod;
    }
    printf("%lld\n",f[n+1]);
    return 0;
}
时间: 2024-10-13 22:25:14

[BZOJ 4767]两双手(组合数学+Dp)的相关文章

bzoj 4767 两双手 - 动态规划 - 容斥原理

题目传送门 传送门I 传送门II 题目大意 一个无限大的棋盘上有一只马,设马在某个时刻的位置为$(x, y)$, 每次移动可以将马移动到$(x + A_x, y + A_y)$或者$(x + B_x, y + B_y)$.棋盘上有$n$个禁止位置不能经过,问马从$(0, 0)$走到$(E_x, E_y)$的方案数. 容斥是显然的. 每确定经过$k$个禁止位置的方案数的容斥系数是$(-1)^{k}$. 考虑带上容斥系数来动态规划, 注意到去掉重复的禁止位置后,$(0, 0), (E_x, E_y)

BZOJ 4767 两双手

题解: 发现这种题目虽然可以想出来,但磕磕碰碰得想挺久的 根据数学可以知道组成方案是唯一的(集合) 然后发现每个使用的大小可能是接近n^2的 直接dp(n^4)是过不了的 那么先观察观察 我们可以把每个障碍点的表示也搞出来 这样就变成了一张网格图求起点到终点的方案数 然后考虑一下容斥,枚举第一个经过的障碍点是谁(之后就随便走了) 然后发现做这个的时候在不断递归 那可以直接按照x,y排个序 依次递推过去 原文地址:https://www.cnblogs.com/yinwuxiao/p/888387

bzoj4767两双手 容斥+组合

4767: 两双手 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 684  Solved: 208[Submit][Status][Discuss] Description 老W是个棋艺高超的棋手,他最喜欢的棋子是马,更具体地,他更加喜欢马所行走的方式.老W下棋时觉得无聊,便 决定加强马所行走的方式,更具体地,他有两双手,其中一双手能让马从(u,v)移动到(u+Ax,v+Ay)而另一双手能让 马从(u,v)移动到(u+Bx,v+By).小W看见老

BZOJ 1076 奖励关(DP)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1076 题意:n种宝物,每个宝物有两个属性: (1)价值:(2)该宝物的集合S,只有得到了集合S中的宝物时才能得到该宝物.每次从一个黑箱子中随机拿出一个宝物k,若k的集合S中的宝物都已经得 到,则k可要(也可不要),否则k不能要.每次拿到任意宝物概率相等.求随机拿K次的最大期望得分. 思路:从后向前,设f[i][j]表示到第i次拿完宝物,状态为j的最大价值.枚举i+1次拿的宝物k,若k的

BZOJ 1801 中国象棋(DP)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1801 题意:在n*m的棋盘上放若干炮使得不互相攻击.有多少种放法?可以放0个.1个....只要不互相攻击就行.. 思路:f[i][j][k]前i行j列有1个炮.k列有两个炮. int n,m; i64 f[N][N][N]; void up(i64 &x,i64 y) { x+=y; x%=mod; } i64 C(int x) { return x*(x-1)/2; } int ma

【bzoj1925】[Sdoi2010]地精部落 组合数学+dp

题目描述 传说很久以前,大地上居住着一种神秘的生物:地精. 地精喜欢住在连绵不绝的山脉中.具体地说,一座长度为 N 的山脉 H可分 为从左到右的 N 段,每段有一个独一无二的高度 Hi,其中Hi是1到N 之间的正 整数. 如果一段山脉比所有与它相邻的山脉都高,则这段山脉是一个山峰.位于边 缘的山脉只有一段相邻的山脉,其他都有两段(即左边和右边). 类似地,如果一段山脉比所有它相邻的山脉都低,则这段山脉是一个山谷. 地精们有一个共同的爱好——饮酒,酒馆可以设立在山谷之中.地精的酒馆 不论白天黑夜总

BZOJ 1925 地精部落(DP)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1925 题意:求1到n个所有排列中有多少种满足高低交错. 思路:f[n][k]表示n个数,最后一个为k且最后两个递增,g[n][k]表示n个数最后一个数为k且最后两个递减.对于f[n][k],若我们将每个数x换为n+1-x,则就成了g[n][n+1-k],因此有:f[n][k]=g[n][n+1-k].那么可得: 由于对称性,我们计算出: 那么最后的答案就是2ans. i64 f[2][

【题解/总结】两双手(格路问题)/格路问题的某一本质

[题解]两双手(格路问题) 题目大意:求从\((0,0)\)到\((Ex,Ey)\)不经过给定障碍点的方案数.你每次移动只能是加上向量\(e_1\)或者向量\(e_2\),\(e_1,e_2\)中的基底都是整数. 考虑转化一下这个问题,从某个点走到在他右上角的某点需要加上\(ae_1+be_2\),这样我们就可以解出\(a,b\).我们把\((a,b)\)拿出来建立新的坐标系,就变成了简单的格路问题了.结合[题解]CF559C C. Gerald and Giant Chess(容斥+格路问题)

Bzoj4767 两双手

Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 553  Solved: 160 Description 老W是个棋艺高超的棋手,他最喜欢的棋子是马,更具体地,他更加喜欢马所行走的方式.老W下棋时觉得无聊,便 决定加强马所行走的方式,更具体地,他有两双手,其中一双手能让马从(u,v)移动到(u+Ax,v+Ay)而另一双手能让 马从(u,v)移动到(u+Bx,v+By).小W看见老W的下棋方式,觉得非常有趣,他开始思考一个问题:假设棋盘是个无限 大的