P1373 小a和uim之大逃離 二維dp

  

題目背景

小a和uim來到雨林中探險。忽然一陣北風吹來,一片烏雲從北部天邊急涌過來,還伴着一道道閃電,一陣陣雷聲。剎那間,狂風大做,烏雲佈滿了天空,緊接着豆大的雨點從天空中打落下來,只見前方出現了一個披頭散髮、青面獠牙的怪物,低沉着聲音說:「呵呵,既然大家來到這,只能活下來一個!」。小a和他的小夥伴都驚呆了!c++

題目描述

瞬間,地面上出現了一個n*m的巨幅矩陣,矩陣的每一個格子上有一坨0~k不等量的魔液。怪物各給了小a和uim一個魔瓶,說道,大家能夠從矩陣的任一個格子開始,每次向右或向下走一步,從任一個格子結束。開始時小a用魔瓶吸取地面上的魔液,下一步由uim吸取,如此交替下去,而且要求最後一步必須由uim吸取。魔瓶只有k的容量,也就是說,若是裝了k+1那麼魔瓶會被清空成零,若是裝了k+2就只剩下1,依次類推。怪物還說道,最後誰的魔瓶裝的魔液多,誰就能活下來。小a和uim感情深厚,情同手足,怎能忍心讓小夥伴離本身而去呢?沉默片刻,小a靈機一動,若是他倆的魔瓶中魔液同樣多,不就都能活下來了嗎?小a和他的小夥伴都笑呆了!ide

如今他想知道他們都能活下來有多少種方法。ui

輸入輸出格式

輸入格式:spa

 

第一行,三個空格隔開的整數n,m,kinput

接下來n行,m列,表示矩陣每個的魔液量。同一行的數字用空格隔開。it

 

輸出格式:class

 

一個整數,表示方法數。因爲可能很大,輸出對1 000 000 007取餘後的結果。方法

 

輸入輸出樣例

輸入樣例#1:  複製
2 2 3
1 1
1 1
輸出樣例#1:  複製
4

看起來很複雜 可是遞推式其實很簡單
狀態主要有 i行 j列 s容量 01兩我的誰拿
注意取答案的時候的操做
還有mod注意一下

注意01下標時的加減

#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define REP(i,N)  for(int i=0;i<(N);i++)
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
#define inf 0x3f3f3f3f
#define N 900
const int mod =(int)1e9+7;
int dp[N][N][20][2];
int mp[N][N];

int main()
{
    int n,m,k;
    RIII(n,m,k);
    k++;
    rep(i,1,n)
    rep(j,1,m)
    RI(mp[i][j]),dp[i][j][mp[i][j]%k][0]=1;

    rep(i,1,n)
    rep(j,1,m)
    rep(s,0,k)
    {
        dp[i][j][s][0]+=(dp[i-1][j][(s-mp[i][j]+k)%k][1])%mod;
        dp[i][j][s][0]+=(dp[i][j-1][(s-mp[i][j]+k)%k][1])%mod;

        dp[i][j][s][1]+=(dp[i-1][j][(s+mp[i][j])%k][0])%mod;
        dp[i][j][s][1]+=(dp[i][j-1][(s+mp[i][j])%k][0])%mod;
    }
    ll cnt=0;
    rep(i,1,n)
    rep(j,1,m)
    {
        cnt=(cnt+dp[i][j][0][1])%mod;
    }
    
    cout<<cnt%mod;

    return 0;
}
相關文章
相關標籤/搜索