dp - Codeforces Round #313 (Div. 1) C. Gerald and Giant Chess
Gerald and Giant Chess #
Problem's Link: http://codeforces.com/contest/559/problem/C
#
Mean:
一个n*m的网格,让你从左上角走到右下角,有一些点不能经过,问你有多少种方法。
analyse:
BZOJ上的原题。
首先把坏点和终点以x坐标为第一键值,y坐标为第二键值排序 。
令fi表示从原点不经过任何坏点走到第i个点的个数,那么有DP方程:
fi=Cxixi+yi−∑(xj<=xi,yj<=yi)C(xi−xj)(xi−xj)+(yi−yj)∗fj
当于枚举第一个遇到的坏点是啥,然后从总方案里减掉。
然后再利用组合数取模就行。
(http://blog.csdn.net/popoqqq/article/details/46121519)
Time complexity: O(N*N)
Source code:
/*
* this code is made by crazyacking
* Verdict: Accepted
* Submission Date: 2015-07-22-23.43
* Time: 0MAXMS
* MAXMemory: 137KB
*/
#include <queue>
#include <cstdio>
#include <set>
#include <string>
#include <stack>
#include <cmath>
#include <climits>
#include <map>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#define mod 1000000007
#define Ulong long unsigned long long
using namespace std;
const int MAXN = 200005;
long long h, w, n, ans;
long long q1[MAXN], q2[MAXN], f[MAXN];
struct point
{
int x, y;
friend bool operator<( point x1, point y1 )
{
if( x1.x != y1.x )return x1.x < y1.x;
return x1.y < y1.y;
}
} a[MAXN];
long long quick_pow( long long x, long long y )
{
long long ans = 1;
while( y )
{
if( y & 1 )ans = ( ans * x ) % mod;
y >>= 1;
x = ( x * x ) % mod;
}
return ans;
}
int main()
{
cin >> h >> w >> n;
for( int i = 1; i <= n; i++ )
cin >> a[i].x >> a[i].y;
for( int i = 0; i < MAXN; ++i )
q1[i] = q2[i] = f[i] = 0;
q1[0] = q2[0] = 1;
sort( a + 1, a + n + 1 );
for( int i = 1; i <= h + w; ++i )
q1[i] = q1[i - 1] * i % mod;
q2[h + w] = quick_pow( q1[h + w], mod - 2 );
for( int i = h + w - 1; i >= 1; i-- )
q2[i] = q2[i + 1] * ( i + 1 ) % mod;
ans = q1[h + w - 2] * q2[h - 1] % mod * q2[w - 1] % mod;
for( int i = 1; i <= n; i++ )
{
f[i] = q1[a[i].x + a[i].y - 2] * q2[a[i].x - 1] % mod * q2[a[i].y - 1] % mod;
for( int j = 1; j < i; j++ )
if( a[j].x <= a[i].x && a[j].y <= a[i].y )
f[i] -= f[j] * q1[a[i].x + a[i].y - a[j].x - a[j].y] % mod * q2[a[i].x - a[j].x] % mod * q2[a[i].y - a[j].y] % mod;
f[i] = ( f[i] % mod + mod ) % mod;
ans = ans - f[i] * q1[h + w - a[i].y - a[i].x] % mod * q2[h - a[i].x] % mod * q2[w - a[i].y] % mod;
}
ans = ( ans % mod + mod ) % mod;
cout << ans << endl;
return 0;
}
* this code is made by crazyacking
* Verdict: Accepted
* Submission Date: 2015-07-22-23.43
* Time: 0MAXMS
* MAXMemory: 137KB
*/
#include <queue>
#include <cstdio>
#include <set>
#include <string>
#include <stack>
#include <cmath>
#include <climits>
#include <map>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#define mod 1000000007
#define Ulong long unsigned long long
using namespace std;
const int MAXN = 200005;
long long h, w, n, ans;
long long q1[MAXN], q2[MAXN], f[MAXN];
struct point
{
int x, y;
friend bool operator<( point x1, point y1 )
{
if( x1.x != y1.x )return x1.x < y1.x;
return x1.y < y1.y;
}
} a[MAXN];
long long quick_pow( long long x, long long y )
{
long long ans = 1;
while( y )
{
if( y & 1 )ans = ( ans * x ) % mod;
y >>= 1;
x = ( x * x ) % mod;
}
return ans;
}
int main()
{
cin >> h >> w >> n;
for( int i = 1; i <= n; i++ )
cin >> a[i].x >> a[i].y;
for( int i = 0; i < MAXN; ++i )
q1[i] = q2[i] = f[i] = 0;
q1[0] = q2[0] = 1;
sort( a + 1, a + n + 1 );
for( int i = 1; i <= h + w; ++i )
q1[i] = q1[i - 1] * i % mod;
q2[h + w] = quick_pow( q1[h + w], mod - 2 );
for( int i = h + w - 1; i >= 1; i-- )
q2[i] = q2[i + 1] * ( i + 1 ) % mod;
ans = q1[h + w - 2] * q2[h - 1] % mod * q2[w - 1] % mod;
for( int i = 1; i <= n; i++ )
{
f[i] = q1[a[i].x + a[i].y - 2] * q2[a[i].x - 1] % mod * q2[a[i].y - 1] % mod;
for( int j = 1; j < i; j++ )
if( a[j].x <= a[i].x && a[j].y <= a[i].y )
f[i] -= f[j] * q1[a[i].x + a[i].y - a[j].x - a[j].y] % mod * q2[a[i].x - a[j].x] % mod * q2[a[i].y - a[j].y] % mod;
f[i] = ( f[i] % mod + mod ) % mod;
ans = ans - f[i] * q1[h + w - a[i].y - a[i].x] % mod * q2[h - a[i].x] % mod * q2[w - a[i].y] % mod;
}
ans = ( ans % mod + mod ) % mod;
cout << ans << endl;
return 0;
}
作者:北岛知寒
出处:https://www.cnblogs.com/crazyacking/p/4669486.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?