zoukankan      html  css  js  c++  java
  • 6544. 【USACO 2020 US Open Platinum】 Sprinklers 2: Return of the Alfalfa

    题目描述

    armer John 有一块小的田地,形状为一个 N 行 N 列的一个方阵(1≤N≤2000),对于所有的 1≤i,j≤N,从上往下的第 i 行的从左往右第 j 个方格记为 (i,j)。他有兴趣在他的田地里种植甜玉米和苜蓿。为此,他需要安装一些特殊的洒水器。
    在方格 (I,J) 中的甜玉米洒水器可以喷洒到所有左下方的方格:即满足 I≤i 以及 j≤J 的 (i,j)。
    在方格 (I,J) 中的苜蓿洒水器可以喷洒到所有右上方的方格:即满足 i≤I 以及 J≤j 的 (i,j)。
    被一个或多个甜玉米洒水器喷洒到的方格可以长出甜玉米;被一个或多个苜蓿洒水器喷洒到的方格可以长出苜蓿。但是被两种洒水器均喷洒到(或均喷洒不到)的方格什么也长不出来。
    帮助 FJ 求出在他的田地里安装洒水器的方法数(模 10^9+7),每个方格至多安装一个洒水器,使得每个方格均能生长作物(即被恰好一种洒水器喷洒到)。
    某些方格正被长毛奶牛占据;这不会阻止这些方格生长作物,但是这些方格里不能安装洒水器。

    N≤2000

    题解

    f[i][j]表示到ij的方案,每次向下或者向右折,加上转角的两个,前缀和优化

    也可以直接维护到ij且上一步为哪个方向

    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
    ",ans);
    	
    	fclose(stdin);
    	fclose(stdout);
    	
    	return 0;
    }
    
  • 相关阅读:
    基于struts2和hibernate的登录和注册功能——完整实例
    (转载)Hibernate的事务管理
    (转载)hibernate缓存
    Hibernate映射解析——七种映射关系
    Hibernate核心组件详解
    Struts2国际化——完整实例代码
    Struts2的手工自定义验证--完整实例代码
    Struts2内置校验器——完整实例代码
    Struts2自定义拦截器——完整实例代码
    Struts2工作原理及流程
  • 原文地址:https://www.cnblogs.com/gmh77/p/12684407.html
Copyright © 2011-2022 走看看