P1373 小a和uim之大逃离

转自:http://www.cnblogs.com/CtsNevermore/p/6028138.html

题目背景

小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取余后的结果。

输入输出样例

输入样例#1:

2 2 3
1 1
1 1

输出样例#1:

4

说明

【题目来源】

lzn改编

【样例解释】

样例解释:四种方案是:(1,1)->(1,2),(1,1)->(2,1),(1,2)->(2,2),(2,1)->(2,2)。

【数据范围】

对于20%的数据,n,m<=10,k<=2

对于50%的数据,n,m<=100,k<=5

对于100%的数据,n,m<=800,1<=k<=15

这题还不算太难,,当初看的时候不是很理解题意,以为他们会选择两条不同的路径,导致整体思路混乱




其实理解题意和思路之后还是敲了不短的时间,一部分身体原因再加上中午休息不太好,整个人思路较乱,靠本能打了一遍代码毫无头绪。恢复了一下状态重新开打,才算是A掉

题解

设dp[i][j][l][p]为当前走到第(i, j)位,当前(a - b) % k 为l,本次是第p个人取得药,p = 0为a,p = 1 为b,
此时的方案数

则 dp[i][j][l][1] += dp[i-1][j][((l + a[i][j]) % k + k) % k][0] + dp[i][j-1][((l + a[i][j]) % k + k) % k][0]

dp[i][j][l][0] += dp[i-1][j][((l - a[i][j]) % k + k) % k][1] + dp[i][j-1][((l - a[i][j]) % k + k) % k][1]

举个栗子:

假设本次在(3, 2),该1(uim)走,则该状态的上一个状态应为 当前在(3,1),该0(小a)走,当时的差为l + a[i][j] 另一个状态同理。

解释一下差加减的原理:

我们的dp方程的第三维定义的是a(小a) - b(uim)的差,那么按照上面的栗子来看,本步由uim来走,那么它们状态的差应减少,减少值为a[i][j],所以上一状态为l + a[i][j],

扯一点关于初始化的东西

由于题目中规定可以从每个点开始,同时必须小a先吸收,所以

对于读入的每一个a[i][j],设dp[i][j][a[i][j] % k][0] = 1

其余点均为0

关于k

实在有些不理解出题人的脑洞,,(lzn别打我= =),,只有k的容量,到了k+1就会清零,,,默默地k++吧

关于复杂度

记录两个人的当前值肯定会T,使用long long会M,据说常数太大会卡两个,暂时没发现

关于差值问题:

有人说差值可正可负,我当时也考虑了一段时间,后来发现在%k意义下对答案没有任何影响,即 k = 3时,(k + 1等于4时)a比b少2和a比b多2其实是等效的,即a拿2个后两人均相同

代码如下:

#include <cstdio>
#include <cstring>
#include <algorithm>

const int maxn = 800 + 1;
const int mod = 1000000007;
int dp[maxn][maxn][16][2];
int a[maxn][maxn];
int n, m, k;

int main () {
    scanf("%d %d %d", &n, &m, &k);
    k++;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            scanf("%d", &a[i][j]);
            dp[i][j][(a[i][j]) % k][0] = 1;
        }
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            for (int l = 0; l < k; l++) {
                dp[i][j][l][1] = (dp[i][j][l][1] + dp[i-1][j][((l + a[i][j]) % k + k) % k][0] + dp[i][j-1][((l + a[i][j]) % k + k) % k][0]) % mod;
                dp[i][j][l][0] = (dp[i][j][l][0] + dp[i-1][j][((l - a[i][j]) % k + k) % k][1] + dp[i][j-1][((l - a[i][j]) % k + k) % k][1]) % mod;
            }
        }
    }
    long long ans = 0;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++) {
            ans = (ans + dp[i][j][0][1]) % mod;
        }
    printf("%lld", ans);

    return 0;
}
 
时间: 2024-10-08 20:50:47

P1373 小a和uim之大逃离的相关文章

洛谷P1373 小a和uim之大逃离

题目背景 小a和uim来到雨林中探险.突然一阵北风吹来,一片乌云从北部天边急涌过来,还伴着一道道闪电,一阵阵雷声.刹那间,狂风大作,乌云布满了天空,紧接着豆大的雨点从天空中打落下来,只见前方出现了一个披头散发.青面獠牙的怪物,低沉着声音说:“呵呵,既然你们来到这,只能活下来一个!”.小a和他的小伙伴都惊呆了! 题目描述 瞬间,地面上出现了一个n*m的巨幅矩阵,矩阵的每个格子上有一坨0~k不等量的魔液.怪物各给了小a和uim一个魔瓶,说道,你们可以从矩阵的任一个格子开始,每次向右或向下走一步,从任

洛谷 P1373 小a和uim之大逃离

题目背景 小a和uim来到雨林中探险.突然一阵北风吹来,一片乌云从北部天边急涌过来,还伴着一道道闪电,一阵阵雷声.刹那间,狂风大作,乌云布满了天空,紧接着豆大的雨点从天空中打落下来,只见前方出现了一个披头散发.青面獠牙的怪物,低沉着声音说:“呵呵,既然你们来到这,只能活下来一个!”.小a和他的小伙伴都惊呆了! 题目描述 瞬间,地面上出现了一个n*m的巨幅矩阵,矩阵的每个格子上有一坨0~k不等量的魔液.怪物各给了小a和uim一个魔瓶,说道,你们可以从矩阵的任一个格子开始,每次向右或向下走一步,从任

luogu P1373 小a和uim之大逃离

题目背景 小a和uim来到雨林中探险.突然一阵北风吹来,一片乌云从北部天边急涌过来,还伴着一道道闪电,一阵阵雷声.刹那间,狂风大作,乌云布满了天空,紧接着豆大的雨点从天空中打落下来,只见前方出现了一个披头散发.青面獠牙的怪物,低沉着声音说:“呵呵,既然你们来到这,只能活下来一个!”.小a和他的小伙伴都惊呆了! 题目描述 瞬间,地面上出现了一个n*m的巨幅矩阵,矩阵的每个格子上有一坨0~k不等量的魔液.怪物各给了小a和uim一个魔瓶,说道,你们可以从矩阵的任一个格子开始,每次向右或向下走一步,从任

洛谷 P1373 小a和uim之大逃离 不会

题目背景 小a和uim来到雨林中探险.突然一阵北风吹来,一片乌云从北部天边急涌过来,还伴着一道道闪电,一阵阵雷声.刹那间,狂风大作,乌云布满了天空,紧接着豆大的雨点从天空中打落下来,只见前方出现了一个披头散发.青面獠牙的怪物,低沉着声音说:“呵呵,既然你们来到这,只能活下来一个!”.小a和他的小伙伴都惊呆了! 题目描述 瞬间,地面上出现了一个n*m的巨幅矩阵,矩阵的每个格子上有一坨0~k不等量的魔液.怪物各给了小a和uim一个魔瓶,说道,你们可以从矩阵的任一个格子开始,每次向右或向下走一步,从任

P1373 小a和uim之大逃离(DP)

(点击此处查看原题) 题意 中文题,题意看题面吧. 解题思路 注意到我们只能向右和下移动,由此想到开二维的dp数组dp[i][j],代表当前所在位置 我们需要让两人取数的差值为0,由于起点和走法的不同,在同一位置上差值可能不同,为此,dp数组再多开一个维度:dp[i][j][p],表示取完位置[i,j]的数后,二者的差值为p 我最开始想到的就是三维度的dp数组,不过写完后发现方程转移就不太灵活了,主要原因在于不知道当前位置是谁进行取数,因为这将影响p的转移 为了让p可以准确的转移,我们为dp数组

小a和uim之大逃离(luogu P1373 dp)

小a和uim之大逃离(luogu P1373 dp) 给你一个n*m的矩阵,其中元素的值在1~k内.限制只能往下和往右走,问从任意点出发,到任意点结束,且经过了偶数个元素的合法路径有多少个.在此题中,定义在一条路径中,第奇数个元素之和为X,第偶数个元素之和为Y.X+Y同模k+1的路径是合法路径.答案模1e9+7.n,m<=800,1<=k<=15. 状态是\(f[i][j][h][0/1]\),表示第i行第j列的元素,奇数元素和X-偶数元素和Y差为h,当前在路径中是第奇数个点或第偶数个点

AC日记——小A和uim之大逃离 II 洛谷七月月赛

小A和uim之大逃离 II 思路: spfa: 代码: #include <bits/stdc++.h> using namespace std; #define INF 0x3f3f3f3f struct NodeType { int x,y,k; NodeType(int x_,int y_,int k_):x(x_),y(y_),k(k_){} NodeType(){} }; const int dx[5]={0,-1,0,1,0}; const int dy[5]={0,0,1,0,-

P3818 小A和uim之大逃离 II(洛谷月赛)

P3818 小A和uim之大逃离 II 题目背景 话说上回……还是参见 https://www.luogu.org/problem/show?pid=1373 吧 小a和uim再次来到雨林中探险.突然一阵南风吹来,一片乌云从南部天边急涌过来,还伴着一道道闪电,一阵阵雷声.刹那间,狂风大作,乌云布满了天空,紧接着豆大的雨点从天空中打落下来,只见前方出现了一个牛头马面的怪物,低沉着声音说:“呵呵,既然你们来到这,两个都别活了!”.小a和他的小伙伴再次惊呆了! 题目描述 瞬间,地面上出现了一个H行W列

[luogu1373]小a和uim之大逃离_dp

小a和uim之大逃离 题目大意:有一个n*m的矩阵.每个格子上有一坨0~k不等量的权值.有两个人,每个人任选一个格子作为出发点,并只能向下或向右走.求最后两个人所得到的权值mod k相等的方案数. 注释:$1\le n,m\le 800$,$1\le k \le 15$. 想法:dp. 状态:dp[i][j][k][0/1]表示在点 (i,j),差值为h,小A还是uim取液体的方案数(0-->小A 1-->uim) 转移: dp[i][j][h][1]+=(dp[i-1][j][(h-a[i]