小a和uim之大逃离_洛谷1373_dp

来源:互联网 发布:动画片 知乎 编辑:程序博客网 时间:2024/06/11 11:10

题目背景


小a和uim来到雨林中探险。突然一阵北风吹来,一片乌云从北部天边急涌过来,还伴着一道道闪电,一阵阵雷声。刹那间,狂风大作,乌云布满了天空,紧接着豆大的雨点从天空中打落下来,只见前方出现了一个披头散发、青面獠牙的怪物,低沉着声音说:“呵呵,既然你们来到这,只能活下来一个!”。小a和他的小伙伴都惊呆了!

题目描述


瞬间,地面上出现了一个n*m的巨幅矩阵,矩阵的每个格子上有一坨0~k不等量的魔液。怪物各给了小a和uim一个魔瓶,说道,你们可以从矩阵的任一个格子开始,每次向右或向下走一步,从任一个格子结束。开始时小a用魔瓶吸收地面上的魔液,下一步由uim吸收,如此交替下去,并且要求最后一步必须由uim吸收。魔瓶只有k的容量,也就是说,如果装了k+1那么魔瓶会被清空成零,如果装了k+2就只剩下1,依次类推。怪物还说道,最后谁的魔瓶装的魔液多,谁就能活下来。小a和uim感情深厚,情同手足,怎能忍心让小伙伴离自己而去呢?沉默片刻,小a灵机一动,如果他俩的魔瓶中魔液一样多,不就都能活下来了吗?小a和他的小伙伴都笑呆了!

现在他想知道他们都能活下来有多少种方法。

输入格式:


第一行,三个空格隔开的整数n,m,k

接下来n行,m列,表示矩阵每一个的魔液量。同一行的数字用空格隔开。

输出格式:


一个整数,表示方法数。由于可能很大,输出对1 000 000 007取余后的结果。

Analysis


一眼dp因为是dp专题(笑

开始是这样想的,f[i][j][a][b]表示走到ij这个位置,小a拿了a和uim拿了b
然后发现题目中小a一定先走第一步,且一定由uim结束(叫你不读题),那么改一下,f[i][j][a][b][0] 用多一维表示当前走到谁

来让我们算一算复杂度,nmk2=80021522=288000000,很显然这么做无论是时间还是空间都会炸,那么又考虑优化(好麻烦)

我们可以发现最终要走到两人拿了相同量的液♂体,也就是a=b,也就是两人的关系可以用他们的差表示,即他们差为0时相等
改过之后的方程f[i][j][k][x]表示当前走到ij,小a和uim取的液体相差k,这一步的液体由x取
显然

f[i][j][k][0]=f[i][j][k][0]+f[i1][j][((k+map[i][j])%k+k)%k][1]+f[i][j1][((k+map[i][j])%k+k)%k][1]

f[i][j][k][1]=f[i][j][k][1]+f[i1][j][((kmap[i][j])%k+k)%k][0]+f[i][j1][((kmap[i][j])%k)%k][0]

好长
对于初值,所有的f[i][j][map[i][j]][0]=1
据说会卡常,反正我没有被卡到
为什么我总要找些恶心的题目来写

Code


#include <stdio.h>#include <string.h>#define rep(i, a, b) for (int i = a; i <= b; i ++)#define fill(x, t) memset(x, t, sizeof(x))#define N 801#define K 17using namespace std;int f[N][N][K][2], map[N][N], MOD = 1000000007;inline int read(){    int x = 0, v = 1;    char ch = getchar();    while (ch < '0' || ch > '9'){        if (ch == '-'){            v = -1;        }        ch = getchar();    }    while (ch >= '0' && ch <= '9'){        x = x * 10 + ch - '0';        ch = getchar();    }    return x * v;}int main(void){    int n = read(), m = read(), p = read();    p ++;    rep(i, 1, n){        rep(j, 1, m){            map[i][j] = read();            f[i][j][map[i][j] % p][0] = 1;        }    }    rep(i, 1, n){        rep(j, 1, m){            rep(k, 0, p - 1){                f[i][j][k][1] = (f[i][j][k][1] + f[i - 1][j][((k + map[i][j])%p + p) % p][0] + f[i][j - 1][((k + map[i][j])%p + p) % p][0]) % MOD;                f[i][j][k][0] = (f[i][j][k][0] + f[i - 1][j][((k - map[i][j])%p + p) % p][1] + f[i][j - 1][((k - map[i][j])%p + p) % p][1]) % MOD;            }        }    }    int ans = 0;    rep(i, 1, n){        rep(j, 1, m){            ans = (ans + f[i][j][0][1]) % MOD;        }    }    printf("%d\n", ans);    return 0;}
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 床头靠背皮掉了怎么办 真皮床头爆皮了怎么办 半裙拉链往下滑怎么办 误用三氧化二砷怎么办 情侣之间感情淡了怎么办 雪纺布料刮坏了怎么办 棉麻布料坏了怎么办 主板针脚弯了怎么办?能修吗? 脸颊两侧毛孔大还有黑头怎么办 脸颊和鼻子粗毛孔大怎么办 十二时辰对照五脏养生在国外怎么办 在学校接吻怕被看到怎么办 楼房圈梁被破坏了怎么办 买了农村的房子怎么办 邻居建房不用共用墙怎么办 腿被蚂蚁咬了怎么办 火车订2票不挨着怎么办 手机全变成英文该怎么办 这些旧电脑该怎么办用英语翻译 落水已把人救出该怎么办 手机落水后已开过机怎么办? 车被洪水冲走了怎么办 感到生活无聊无事可干怎么办 邻居不除排水沟影响到自己怎么办 开过光的玉碎了怎么办 一脚刹车踩到底怎么办 p53基因型cc型该怎么办 人不小心掉进火山怎么办 奥林巴斯相机相片被锁了怎么办 文明53格外的奢侈品怎么办 答应了要请客钱不够怎么办 在家里面着急没办法干活怎么办 1岁宝宝脾气暴躁怎么办 档案不在中国海峡人才市场怎么办 海丰西中街吃鸡钱包给拿了怎么办? 朝鲜成为经济强国中国怎么办 窗户上有哈气水怎么办 阳台下水管声音好大怎么办 一开水龙头会响怎么办 海里遇到暗流怎么办贴吧 东海通忘记客户号怎么办