洛谷OJ 1373 小a和uim之大逃離 DP
阿新 • • 發佈:2017-05-09
方法 blog brush cnblogs 計算 memset end namespace cpp
https://www.luogu.org/problem/show?pid=1373
題意:n*m地圖,n,m<=800,起點,終點任意,兩個人每次輪流取出點中的數並膜K,問走奇數次 兩人取值相同的方法數?
只關心兩人取的值是否相等,則記錄差值即可
起點和終點任意 則設狀態dp[i][j][k][p] 到達點(i,j)差值為k 並且由p取數的方法數
不用枚舉起點,暴力把所有狀態的方案都計算出來即可,復雜度為O(n*m*k)
#include <bits/stdc++.h> using namespace std; typedef long long ll; const ll mod=1e9+7; const int N=805; int dp[N][N][16][2],n,m,k,a[N][N]; int main() { while(cin>>n>>m>>k) { ll ans=0; memset(dp,0,sizeof(dp)); 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]][0]=1; k++;// for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { for(int l=0;l<k;l++) { //eg:設a得分為s,b得分為t,a-b的差=l-> s-(t+a[i][j]) =l 上局為s-t=l+a[i][j] dp[i][j][l][1]=(dp[i][j][l][1]+dp[i-1][j][(l+a[i][j])%k][0]+dp[i][j-1][(l+a[i][j])%k][0])%mod; //eg:a-b s+a[i][j]-t=l s-t=l-a[i][j] int pre=(l-a[i][j]+k)%k; dp[i][j][l][0]=(dp[i][j][l][0]+dp[i-1][j][pre][1]+dp[i][j-1][pre][1])%mod; } } } for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { ans=(ans+dp[i][j][0][1])%mod; } } cout<<ans<<endl; } return 0; }
洛谷OJ 1373 小a和uim之大逃離 DP