最短路线

  • 题目描述
    – 某城市的街道是一个很规整的矩形网格(见下图),有 M 条南北向的纵街,N 条东西向的横街。现要从西南角的 A 走到东北角的 B,最短的走法共有多少种?

  • 输入
    – 输入文件 Sline.in,一行,两个数 M,N,其中 2 < M,N <= 800

  • 输出
    – 输出文件 sline.out,输出最短路的走法总数.
  • 样例输入
    7 5
  • 样例输出
    210
  • 数据范围限制
    【限制】
    – 对于 30%的数据, 2 < M,N <= 30;
    – 对于 60%的数据, 2 < M,N <= 100;
    – 对于 100%的数据, 2 < M,N <= 800;

题解:

- 这道题是高精度里的dp
- 首先,走到一个点的方法总数,就等于走到上一个点的方法之和    所以说:

dp[i][j]=dp[i-1][j]+dp[i][j-1]

-- 然后发现答案最大的一个有450多位,就套一个高精度加法就行了
-- 但是!!! 开始我就直接用最简单的高精度,竟然平生第一次爆空间!!!
-- 所以还要压位(在数组一个元素里存更多的位数)
-- 最后注意要把用来记录进位的变量也定义为longlong(预防迷之错误)

代码:

#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
const int MAXN=805;
const long long mod=1e16;

int n,m;
struct hehe {
    long long A[50];
    int l;
    hehe() {
        for(int i=0; i<=39; i++)
            A[i]=0;
        l=0;
    }
};
hehe step[MAXN][MAXN];
void add(hehe &a,hehe &b,hehe &c) {
    long long x=0;
    while(c.l<=a.l||c.l<=b.l) {
        c.A[c.l]=a.A[c.l]+b.A[c.l]+x;
        x = 0;
        if(c.A[c.l]>=mod) {
            x=c.A[c.l]/mod;
            c.A[c.l]%=mod;
        }
        c.l++;
    }
    c.A[c.l]=x;
    while(!c.A[c.l])
        c.l--;
}

int main() {
//  freopen("sline.in","r",stdin);
//  freopen("sline.out","w",stdout);
    cin>>m>>n;
    step[0][1].A[0]=1;
    step[0][1].l=0;
    for(int i=1; i<=n; i++)
        for(int j=1; j<=m; j++)
            add(step[i-1][j],step[i][j-1],step[i][j]);
    for(int i=step[n][m].l; i>=0; i--)
        if(i==step[n][m].l)
            cout<<step[n][m].A[i];
        else
            printf("%016lld",step[n][m].A[i]);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值