洛谷 P1373 小a和uim之大逃离 (差值型dp总结)

这道题和多米诺骨牌那道题很像

,都是涉及到差值的问题。
这道题是二维的,同时要取模.
这种题,因为当前的决策有后效性,会影响到差值,所以直接把
差值作为维度,然后计算答案的时候把差值为0的加起来就行了。
这里有两个人,所以可以多设一维第一人还是第二人,来回更新。
然后取模的时候记得+k再模k

#include<cstdio>
#include<algorithm>
#define REP(i, a, b) for(int i = (a); i < (b); i++)
#define _for(i, a, b) for(int i = (a); i <= (b); i++)
#define cal(a, b) a = (a + b) % MOD //这句话省了巨多代码!! 
using namespace std;

const int MAXN = 805;
const int MAXM = 16;
const int MOD = 1e9 + 7;
int f[MAXN][MAXN][MAXM][2];
int a[MAXN][MAXN], n, m, k, ans;

int main()
{
	scanf("%d%d%d", &n, &m, &k); k++;
	_for(i, 1, n)
		_for(j, 1, m)
		{
			scanf("%d", &a[i][j]);
			f[i][j][a[i][j]%k][0] = 1;
		}
	
	_for(i, 1, n)
		_for(j, 1, m)
			REP(h, 0, k)
			{
				cal(f[i][j][h][0], f[i-1][j][(h-a[i][j]+k)%k][1] + f[i][j-1][(h-a[i][j]+k)%k][1]);
				cal(f[i][j][h][1], f[i-1][j][(h+a[i][j])%k][0] + f[i][j-1][(h+a[i][j])%k][0]);
				if(h == 0) cal(ans, f[i][j][0][1]);
			}
	
	printf("%d\n", ans);
	
	return 0;
}


 

posted @ 2018-09-10 18:22  Sugewud  阅读(130)  评论(0编辑  收藏  举报