6544. 【USACO 2020 US Open Platinum】 Sprinklers 2: Return of the Alfalfa

Title description

armer John has a small field in the shape of a square matrix with N rows and N columns (1≤N≤2000). For all 1≤i, j≤N, the i-th row from top to bottom The jth square on the right is marked as (i, j). He is interested in growing sweet corn and alfalfa in his fields. For this, he needs to install some special sprinklers.
The sweet corn sprinkler in the square (I, J) can be sprayed to all the lower left squares: (i, j) that satisfies I ≤ i and j ≤ J.
The alfalfa sprinkler in the square (I, J) can be sprayed to all the upper right squares: namely (i, j) satisfying i ≤ I and J ≤ j.
The square sprayed by one or more sweet corn sprinklers can grow sweet corn; the square sprayed by one or more alfalfa sprinklers can grow alfalfa. But the square that was sprayed by both sprinklers (or neither) could grow nothing.
Help FJ find the number of methods to install sprinklers in his field (modulo 10 ^ 9 + 7), install at most one sprinkler in each square, so that each square can grow crops (that is, just one kind of sprinkler) Sprayer).
Some squares are being occupied by long-haired cows; this will not prevent these squares from growing crops, but sprinklers cannot be installed in these squares.

N≤2000

answer

f [i] [j] represents the plan to ij, each time it is folded down or right, plus two corners, prefix and optimization

It can also be directly maintained to ij and which direction is the previous step

code

#include <bits/stdc++.h>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define add(a,b) a=((a)+(b))%1000000007
#define mod 1000000007
#define two 500000004
#define ll long long
#define file
using namespace std;

ll f[2001][2001],p[2001],sum[2001],Sum,sum2,ans;
bool a[2001][2001];
int n,i,j,k,l;
char ch;

ll qpower(ll a,int b) {ll ans=1;while (b) {if (b&1) ans=ans*a%mod;a=a*a%mod;b>>=1;} return ans;}

int main()
{
	freopen("sprinklers2.in","r",stdin);
	#ifdef file
	freopen("sprinklers2.out","w",stdout);
	#endif
	
	scanf("%d",&n);p[0]=1;
	fo(i,1,n)
	{
		p[i]=p[i-1]*2%mod;
		fo(j,1,n)
		{
			ch=getchar();while (ch!='.' && ch!='W') ch=getchar();
			a[i][j]=ch=='W';sum[i]+=!a[i][j];
		}
		Sum+=sum[i];
	}
	
//	---
	
	fo(j,1,n)
	{
		if (j>1)
		{
			if (!a[1][j-1])
			f[1][j]=p[sum[1]-1];
		}
		else
		f[1][j]=p[sum[1]];
	}
	if (!a[1][n]) ans=qpower(2,Sum-1);
	
	fo(i,1,n-1)
	{
		Sum-=sum[i];sum2=0;
		
		fo(j,1,n)
		{
			add(f[i+1][j],f[i][j]*p[sum[i+1]]);
			
			if (j>1 && !a[i+1][j-1]) add(f[i+1][j],sum2);
			if (!a[i][j]) add(sum2,f[i][j]*p[sum[i+1]-1]%mod*two);
			
			if (!a[i][j] && !a[i+1][n])
			add(ans,f[i][j]*qpower(2,Sum-1)%mod*two);
		}
	}
	fo(j,1,n)
	if (!a[n][j])
	add(ans,f[n][j]*two);
	
	printf("%lld\n",ans);
	
	fclose(stdin);
	fclose(stdout);
	
	return 0;
}

Guess you like

Origin www.cnblogs.com/gmh77/p/12684407.html