跳跃版图

题目:跳跃版图

题目描述

有一个 n×n 的格子,每个格子中有一个非负整数。你的目标是从左上角跳到右下角,每步只能向右或向下跳。格子中的数代表从该格开始跳跃的前进步数,如果某次跳跃会跃出格子界限则该跳跃是禁止的。注意是一个绝对终点,因为从这里无法再移动。

你的任务是统计有多少种合法路径。上图中共有种路径,分别表示在图中。

输入说明

第一行,一个整数 n。

接下来列,表示格子中的数,所有数的范围在[0,9]中,两个数之间用一个空格隔开。

输出说明

第一行,从左上角到右下角的合法路径数目。

输入样例

4

2 3 3 1

1 2 1 3

1 2 3 1

3 1 1 0

输出样例

3

数据范围

共有 20 组数据,每组分。至少组数据,n<=12。

至少 14 组数据,n<=35。

对于所有数据,3<=n<=100。

 

类似过河卒的dp,不过需要高精度,李国豪(清华)学长写得高精度赞得很,学一波!

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
long long n,x;
void in(long long &x)
{
    char c=getchar();x=0;
    while(c<'0'||c>'9')c=getchar();
    while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
}

struct num
{
    int a[200],l;
    void clr()
    {
        memset(a,0,sizeof(a));
        a[0]=1;a[1]=0;
        l=1;
    }
    void operator +=(const num &b)
    {
        if(b.l>l) l=b.l;
        for(int i=1;i<=l;i++)
        {
            a[i]+=b.a[i];
            a[i+1]+=a[i]/10;
            a[i]%=10;
        }
        if(a[l+1]>0) l++;
    }
    void out()
    {
        for(int i=l;i>=1;i--)
        cout<<a[i];
    }
}f[110][110];

int main()
{
    freopen("jump.in","r",stdin);
    freopen("jump.out","w",stdout);
 in(n);
 for(int i=1;i<=n;i++)
   for(int j=1;j<=n;j++)
     f[i][j].clr();
     f[1][1].a[1]=1;
 for(long long i=1;i<=n;i++)
   for(long long j=1;j<=n;j++)
    {
        in(x);
        if(i+x<=n&&x!=0) f[i+x][j]+=f[i][j];
        if(j+x<=n&&x!=0) f[i][j+x]+=f[i][j];
    }
    f[n][n].out();
 return 0;
}

 

posted @ 2017-08-22 16:30  WeiAR  阅读(159)  评论(0编辑  收藏  举报