A digital dp exercises

Reference blog

The meaning of problems

Given an n * m grid graph, a start and a destination on the map (there is no obstacle at the start and end), and a number of obstacles, for each of the digits 0-9 are a pair of numbers will be given of (ai, bi). For a number t, we sweep from high to low again, i t for each digit of the current position of the line plus the plus column ai bi, if from the beginning of the simulation process can not and does not come out of the border barriers final reach the end, the number of said valid trellis diagram for the current t. T the number of valid number within the number range Q [L, R], the answer to the modulo 1,000,000,007.
It is not the way to reach the end. Mobile is instantaneous.

data range

20% of the data 1 <= L <= R < = 10000.
40% of the data 1 <= L <= R < = 1,000,000,000 and RL <= 1000000.
60% of the data 1 <= L <= R < = 10 ^ 18.
Another 10% of the data of all ai = bi = 0.
100% data 0 <n, m <= 50 , | ai | <= n, | bi | <= m, 1 <= L <= R <= 10 ^ 500 0 no preamble.

solution

First title mean numbers 0-9, respectively, represent a moves from (x, y) went to (x + ai, y + bi )
may initially be somewhat at a loss, then think about it can be found from high to low determining each of t.
and then began to consider the number of bits DP, from the most significant bit to a low DP, recorded f [now] [x] [ y] [flag] represents now swept bit i, come (x, y) and the presence or absence of leading zeros (record leading zeros because there might be a starting point the focus of coincidence) the number of schemes. then the memory of the search on it.

#include<bits/stdc++.h>
using namespace std;
const int mod=1000000007;
int n,m;
char mp[55][55];
int dx[10],dy[10];
int sx,sy,tx,ty;
inline bool can(int x,int y) {return (x<=n&&x>=1&&y<=m&&y>=1)&&mp[x][y]!='*';}
bool check(char *x){
	int len=strlen(x+1);
	int alfa=sx,beta=sy;
	for(int i=1;i<=len;i++){
		alfa+=dx[x[i]-'0'];
		beta+=dy[x[i]-'0'];
		if (!can(alfa,beta)) return false;
	}
	return alfa==tx&&beta==ty;
}
int f[505][55][55][2];int a[505];
int dfs(int pos,int x,int y,bool lim,bool zero){
	if (!can(x,y)) return 0;
	if (pos<=0) return !zero&&x==tx&&y==ty;
	if (!lim&&~f[pos][x][y][zero]) return f[pos][x][y][zero];
	int top=lim?a[pos]:9;int res=0;
	for(int i=0;i<=top;i++){
		if (i==0&&zero){(res+=dfs(pos-1,x,y,lim&&i==top,1))%=mod;continue;}
		(res+=dfs(pos-1,x+dx[i],y+dy[i],lim&&i==top,0))%=mod;
	}
	if(!lim)f[pos][x][y][zero]=res;
	return res;
}
int count(char *x){
	int len=strlen(x+1);
	for(int i=1;i<=len;i++) a[i]=x[len-i+1]-'0';
	return dfs(len,sx,sy,1,1);
}
char L[505],R[505];
int main(){
	//freopen("1.in","r",stdin);
	//freopen("1.out","w",stdout);
	memset(f,-1,sizeof f);
	scanf("%d%d",&n,&m);
	scanf("%s%s",L+1,R+1);
	for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){
		char& c=mp[i][j];
		for (c=getchar();c!='1'&&c!='2'&&c!='3'&&c!='*'&&c!=' ';c=getchar());
		if (c=='1') sx=i,sy=j;
		if (c=='2') tx=i,ty=j;
		if (c=='3') sx=tx=i,sy=ty=j;
	}
	for(int i=0;i<=9;i++) scanf("%d%d",&dx[i],&dy[i]);
	printf("%d\n",((count(R)-count(L)+check(L))%mod+mod)%mod);
}

Published 62 original articles · won praise 1 · views 978

Guess you like

Origin blog.csdn.net/wmhtxdy/article/details/103906109