luogu P1373 小a和uim之大逃离 动态规划

由于几天在洛谷颓废只打卡不做题的行为 我的洛谷账号成功掉到了绿名…
所以这几天发点洛谷上的题 先搞个动归练练手
题面
d p [ i ] [ j ] [ k ] [ 0 / 1 ] dp[i][j][k][0/1] dp[i][j][k][0/1]表示当前走到了 i i i j j j列时二人魔液数 ?? 相差 k k k个时 该轮到小A/小uim拿的方案数
有点长…其实就是 i    j i\,\,j ij表示走到了哪 k k k表示二人魔液数差多少 0是小A拿 1是小uim拿
很容易可以看出 d p dp dp式:
d p [ i ] [ j ] [ l ] [ 0 ] + = d p [ i − 1 ] [ j ] [ ( l − s q r [ i ] [ j ] + k ) % k ] [ 1 ] ; dp[i][j][l][0]+=dp[i-1][j][(l-sqr[i][j]+k)\%k][1]; dp[i][j][l][0]+=dp[i1][j][(lsqr[i][j]+k)%k][1];
d p [ i ] [ j ] [ l ] [ 0 ] + = d p [ i ] [ j − 1 ] [ ( l − s q r [ i ] [ j ] + k ) % k ] [ 1 ] ; dp[i][j][l][0]+=dp[i][j-1][(l-sqr[i][j]+k)\%k][1]; dp[i][j][l][0]+=dp[i][j1][(lsqr[i][j]+k)%k][1];
d p [ i ] [ j ] [ l ] [ 1 ] + = d p [ i − 1 ] [ j ] [ ( l + s q r [ i ] [ j ] + k ) % k ] [ 0 ] ; dp[i][j][l][1]+=dp[i-1][j][(l+sqr[i][j]+k)\%k][0]; dp[i][j][l][1]+=dp[i1][j][(l+sqr[i][j]+k)%k][0];
d p [ i ] [ j ] [ l ] [ 1 ] + = d p [ i ] [ j − 1 ] [ ( l + s q r [ i ] [ j ] + k ) % k ] [ 0 ] ; dp[i][j][l][1]+=dp[i][j-1][(l+sqr[i][j]+k)\%k][0]; dp[i][j][l][1]+=dp[i][j1][(l+sqr[i][j]+k)%k][0];
不多bb浪费篇幅 直接上代码

#include<bits/stdc++.h>
using namespace std;
#define reg register
const int mod=1e9+7;
inline void read(int &x){
    
    
    int s=0,w=1;char ch=getchar();
    while(ch<'0'||ch>'9'){
    
    if(ch=='-')w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){
    
    s=(s<<3)+(s<<1)+(ch&15);ch=getchar();}
    x=s*w;
}
int n,m,k,ans,dp[801][801][16][2],sqr[801][801];
int main(){
    
    
    read(n),read(m),read(k);k++;
    for(reg int i=1;i<=n;i++){
    
    
        for(reg int j=1;j<=m;j++){
    
    
            read(sqr[i][j]);
            sqr[i][j]%=k;
            dp[i][j][sqr[i][j]][0]=1;
        }
    }
    for(int i=1;i<=n;i++){
    
    
        for(int j=1;j<=m;j++){
    
    
            for(int l=0;l<k;l++){
    
    
                if(i>1)(dp[i][j][l][0]+=dp[i-1][j][(l-sqr[i][j]+k)%k][1])%=mod;
                if(j>1)(dp[i][j][l][0]+=dp[i][j-1][(l-sqr[i][j]+k)%k][1])%=mod;
                if(i>1)(dp[i][j][l][1]+=dp[i-1][j][(l+sqr[i][j]+k)%k][0])%=mod;
                if(j>1)(dp[i][j][l][1]+=dp[i][j-1][(l+sqr[i][j]+k)%k][0])%=mod;
            }
        }
    }
    for(int i=1;i<=n;i++){
    
    
        for(int j=1;j<=m;j++){
    
    
            (ans+=dp[i][j][0][1])%=mod;
        }
    }
    printf("%d\n",ans);
}

猜你喜欢

转载自blog.csdn.net/dhdhdhx/article/details/102490197