1235 -- 古明地觉的节操教育

Description

对于下述条件计算恋恋拿到礼物有几种走法。 
给一个N*M的图,恋恋起始在左上角,坐标(1,1),面向右或者面向下,礼物坐标在(X,Y),图以外的区域全是洞,图以内还有K个洞,所有在洞上的东西都会掉下去,包括道具和路标。小五现在没有道具可以使用,但是有无限个指向右的路标和无限个指向下的路标可以使用。

小五可以在任意空地上放置道具和路标,恋恋只会无意识的向前走。 
如果恋恋前面一格有路标,恋恋就会看一样路标,并往路标指的方向走。 
如果恋恋前面一格的路标的指向和恋恋的走向一样,恋恋就会无视它,并且踩过去。  
如果恋恋当前格子是洞,恋恋就会掉下去。 

Input

输入数据第一行有三个整数N、M、K、X、Y(3<=N,M<1000,0<=K<n*m,1<=x<=n,1<=y<=m)
以下有K行,每行有两个整数Xi、Yi(1<=Xi<=N,1<=Yi<=M)第i个洞的坐标为(Xi,Yi) 
数据保证每个洞和恋恋和礼物的位置均不同 

Output

输出恋恋拿到礼物的走法数mod 10007的余数

Sample Input

4 4 1 3 4
2 2

Sample Output

2

Hint

样例中恋恋的两种走法分别是: 
1.下下右右右 
2.右右下下右 


动态规划,每个位置有向右,向下两种状态.状态仅向右和向下转移,检查状态转移的合法性,瞎写一下。

#include <cstdio>  
#include <iostream>  
#include <algorithm>
using namespace std;  
#define for1(i, n) for (int i = 1; i <= n; i++)  
//  head  
const int mod = 10007;  
const int maxn =1005;  
int dp[maxn][maxn][2];  
int vi[maxn][maxn];  
int main() {   
    int n, m, k, x, y, xi, yi;  
    cin>> n >> m >> k >> x >> y;  
    for1(i, k) cin >> xi >> yi, vi[xi][yi] = 1;  
    for1(i, n) vi[i][m + 1] = 1;  
    for1(i, m) vi[n + 1][i] = 1;  
    //初始化状态转移  
    if(!vi[1][2]) dp[1][2][1] = 1;  
    if(!vi[2][1]) dp[2][1][0] = 1;  
    //0 向下 1 向右 dp[i][j][0] 表示达到(i,j)时状态为向下的方案数  
    for1(i, n)  
        for1(j, m) {  
            if(i == 1 && j == 1) {continue;}  
            if(dp[i][j][0]) {  
                if(!vi[i + 1][j])  
                    dp[i + 1][j][0] = (dp[i + 1][j][0] + dp[i][j][0]) %mod;  
                if(!vi[i + 1][j] && !vi[i][j + 1])  
                    dp[i][j + 1][1] = (dp[i][j + 1][1] + dp[i][j][0]) %mod;  
            }  
            if(dp[i][j][1]) {  
                if(!vi[i][j + 1])  
                    dp[i][j + 1][1] = (dp[i][j + 1][1] + dp[i][j][1]) %mod;  
                if(!vi[i][j + 1] && !vi[i + 1][j])  
                    dp[i + 1][j][0] = (dp[i + 1][j][0] + dp[i][j][1]) %mod;  
            }  
    }  
    cout<<(dp[x][y][0] + dp[x][y][1]) %mod<<endl;  
    return 0;  
}  


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值