(DP)Ivan the Fool and the Probability Theory---------- Codeforces Round #594 (Div. 2)

https://codeforces.com/contest/1248/problem/C

题意:给定一个N×M大小的方格图,现在要求将每个格子染成黑白两种颜色,要求每个格子至多和四个方向(上下左右)上的一个格子同色,问有多少种方案。

思路:当我们确定了第一行或第一列后,整张图的结构就被我们确定了。

若第一行存在两个连续的颜色相同的格子且已经确定了第一行的颜色,那么下面每一行的结构就确定了,可以任意画图验证,无论这两个相邻块之前或者之后是什么颜色,下面那行的颜色一定与上面一行相反,单独从列上看,每一列都是黑白相互交错的(先将黑白相间的两种情况排除),那么为要先排除一行中有黑白相互交错的情况?例如010101,下面那行可以是101010,或者010101,不能唯一确定,所以先排除他

我们从列上看,若每一列存在两个连续的颜色相同的格子且已经确定了第一列的颜色,每一行的颜色都是由第一列的颜色决定的,(注意是第一列),画图可以发现,从列上去确定每一行的颜色,每一行都是黑白相间的,那么这也就解释了为什么之前要先排除每行上面黑白相间的两种情况。

总结来说就是 如果第一列的元素是严格黑白相间的话,那么每一行都是由第一列的颜色决定的(注意是第一列),dp第一列的情况,若第一行不是严格黑白相间,那么后面几行都是固定的

 

所以可以开始写转移方程了,设dp[i][0]是长度为i的格子且颜色为白色的方案数,dp[i][1]是长度为i的格子且颜色为黑色的方案数,

那么先考虑边界条件

一个格子,只能黑色或者白色,即dp[1][0]=1,dp[1][1]=1;

两个格子,dp[2][0]=2,因为无论前面那个格子可是是黑色或者白色,所以有两种方案,同理dp[2][1]=2

边界条件确定后,就可以dp出其他的了

最后得到dp[i]=dp[i-1]+dp[i-2]

#include

using namespace std;
typedef long long ll; 
inline int read(){
    int X=0,w=0;char ch=0;
    while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
    while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
    return w?-X:X;
}
/*------------------------------------------------------------------------*/
const int maxn=1e5+10; 
const int mod=1e9+7; 
int dp[maxn];

int main()
{	
	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    //freopen("a.txt","r",stdin);
    //freopen("a.txt","w",stdout);
    int n,m;
    cin>>n>>m;
    
    dp[1]=2;
    dp[2]=4;
    
    for(int i=3;i<=max(n,m);++i){
    	
    	dp[i]=(dp[i-1]+dp[i-2])%mod;
    	
    	
    }
    cout<<(dp[n]+dp[m]-2)%mod<

感谢几位大佬的博客

https://blog.csdn.net/weixin_42856843/article/details/102655689#commentsedit

https://blog.csdn.net/toohandsomeIeaseId/article/details/102668813#commentsedit

https://blog.csdn.net/qq_37656398/article/details/102660797

 

你可能感兴趣的:(codeforce)