51Nod 1486 大大走格子

Problem

有一个h行w列的棋盘,里面有一些格子是不能走的,现在要求从左上角走到右下角的方案数。(只能向右和向下走)

Solution

黑点里加入右下的点,每个点求一个ans[i],代表走到这个点的方案数。

ans[i]初始为C(n+m-2,m-1),对于所有在它左上的点,都减去那个点的ans[j]乘i、j之间的方案数。

(每个黑点,求ans的时候是求:不经过其左上所有的黑点,到它的方案数;用的时候是减去:经过这个点到右下的所有可能,此时路径没有经过当前黑点左上的黑点,因此每个黑点的ans是独立的。)

Code

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
typedef long long ll;
typedef long double ld;
typedef double db;
#define io_opt ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
const int mod=1e9+7;
inline int mo(ll a,int p){
    return a>=p?a%p:a;
}
inline int rd() {
    int x = 0, f = 1;
    char ch;
    while (ch < '0' || ch > '9') {
        if (ch == '-')f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return f * x;
}
inline ll gcd(ll x, ll y){
    return y==0?x:gcd(y,x%y);
}
inline ll speed(ll a,ll b,int p){
    ll cur=a,anss=1;
    while(b){
        if(b&1) anss=anss*cur%p;
        cur=cur*cur%p;
        b>>=1;
    }
    return anss%p;
}
const int MAXN=1e5;
bool ipr[MAXN+20];
int cnt,pri[MAXN/5];
void prime(){//埃式筛法
    int N=sqrt(MAXN)+0.5,mul;
    memset(ipr,true,sizeof(ipr));
    ipr[1]=false;
    for(int i=2;i<=N;i++){
        if(ipr[i]==true){
            i==2?mul=1:mul=2;
            for(int j=i*i;j<=MAXN;j+=i*mul){
                ipr[j]=false;
            }
        }
    }
    for(int i=2;i<=MAXN;i++){
        if(ipr[i]==true){
            pri[++cnt]=i;
        }
    }
}
int n,m,t;
struct E{
    int x,y;
    ll ans;
}e[2020];
int cmp(E x,E y){
    if(x.x==y.x) return x.y

你可能感兴趣的:(51Nod 1486 大大走格子)