【LUOGU P1373】小a和uim之大逃离(递推dp)

xiaoxiao2022-06-11  24

传送门QWQ

dp[i][j][h][l] 表示在点 (i,j),差值为h,小A还是uim取液体的方案数(0:小A 1:uim)

转移方程:

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

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

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

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

初始化:dp[i][j][a[i][j]][0]=1; 一开始小A可以从任意点开始

我一开始一直在纠结A吸毒液和B吸毒液的区别 一直想不通为什么一个是+a[i][j],一个是-a[i][j],其实很简单,因为两个人是A取一次 B再取一次的 A吸毒液 相当于给整体的差值加了k B吸毒液 相当于给整体的差值减了k

// luogu-judger-enable-o2 #include<bits/stdc++.h> #define N 805 #define mod 1000000007 using namespace std; int n,m,K,a[N][N],dp[N][N][18][2]; //0:小A 1:uim typedef long long ll; int main() { ios::sync_with_stdio(false); cin.tie(NULL);cout.tie(NULL); cin>>n>>m>>K; K++; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { cin>>a[i][j]; dp[i][j][a[i][j]][0]=1; } } for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { for(int k=0;k<=K-1;k++) { dp[i][j][k][0]=(dp[i][j][k][0]+dp[i-1][j][(k-a[i][j]+K)%K][1])%mod; dp[i][j][k][0]=(dp[i][j][k][0]+dp[i][j-1][(k-a[i][j]+K)%K][1])%mod; dp[i][j][k][1]=(dp[i][j][k][1]+dp[i-1][j][(k+a[i][j])%K][0])%mod; dp[i][j][k][1]=(dp[i][j][k][1]+dp[i][j-1][(k+a[i][j])%K][0])%mod; } } } ll ans=0; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { ans=(ans+ll(dp[i][j][0][1]))%mod; } cout<<ans<<endl; return 0; }
转载请注明原文地址: https://www.6miu.com/read-4930413.html

最新回复(0)