Gerald and Giant Chess(计数dp+组合数学)
codeforces 559C Gerald and Giant Chess
题目大意:就是说给你一个h*w的矩阵,让你从(1,1)走到(h,w)问你右多少种走法
计算左上到右下的方法如果不考虑黑点的话,sum=C(h+w)(h)
因为存在黑点i(x,y),所以用所以计算从左上到黑点的方法有sum[i] = C(x+y)(x),其中如果在黑点的左上还有黑点j(u,v),那么应该减去sum[j]*C(x-u+y-v)(y-u),去掉所有在左上的黑点的影响就可以得到由左上到第i点的真正的方法数
从左上的第一个黑点,一直计算到右下(h,w)
注意一定要减去sum[j]
#include<iostream> #include<algorithm> using namespace std; typedef long long ll; const int maxn=1e6+100; const int mod=1e9+7; ll f[maxn]; ll sum[maxn]; int h,w,n; struct node{ int x,y; }a[maxn]; bool cmp(node a,node b){ if(a.x==b.x){ return a.y<b.y; } else{ return a.x<b.x; } } ll qpow(ll a,ll b){ ll ans=1; while(b){ if(b&1){ ans=(ans*a)%mod; } a=(a*a)%mod; b/=2; } return ans%mod; } void inint(){ f[1]=1; for(int i=2;i<=2e5+1;i++){ f[i]=(f[i-1]*i)%mod; } } ll C(ll n,ll m){ if(m==0||n==m){//注意调试了半天 return 1ll; } ll ans=(((f[n]%mod*qpow(f[m],mod-2))%mod*qpow(f[n-m],mod-2))%mod)%mod; return ans%mod; } int main(){ inint(); cin>>h>>w>>n; for(int i=0;i<n;i++){ cin>>a[i].x>>a[i].y; } a[n].x=h,a[n++].y=w; sort(a,a+n,cmp); int x1,y1,x2,y2; for(int i=0;i<n;i++){//找的是起点 x1=a[i].x-1;y1=a[i].y-1;//为什么要减1呢,就是从1,1到2,3要向下1步,向右2个,所以要减1 sum[i]=C(x1+y1,x1)%mod; for(int j=0; j<i ;j++){ if(a[j].x<=a[i].x && a[j].y<=a[i].y){ x2=x1-a[j].x+1,y2=y1-a[j].y+1; ll p=C(x2+y2,x2)*sum[j]%mod; sum[i]=(sum[i]-p+mod)%mod; } } } cout<<sum[n-1]<<endl; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理