zoukankan      html  css  js  c++  java
  • CF1051D Bicolorings

    CF1051D Bicolorings

    洛谷传送门

    题目描述

    You are given a grid, consisting of 22 rows and nn columns. Each cell of this grid should be colored either black or white.

    Two cells are considered neighbours if they have a common border and share the same color. Two cells AA and BB belong to the same component if they are neighbours, or if there is a neighbour of AA that belongs to the same component with BB .

    Let's call some bicoloring beautiful if it has exactly kk components.

    Count the number of beautiful bicolorings. The number can be big enough, so print the answer modulo 998244353998244353 .

    输入格式

    The only line contains two integers nn and kk ( 1 le n le 10001≤n≤1000 , 1 le k le 2n1≤k≤2n ) — the number of columns in a grid and the number of components required.

    输出格式

    Print a single integer — the number of beautiful bicolorings modulo 998244353998244353 .

    题意翻译

    题目大意:

    给定一个2 imes n2×n的棋盘,可以对上面的格子黑白染色,求染色后棋盘上的联通块的个数正好为kk的染色方案数

    输入格式:

    一行两个整数n,kn,k

    输出格式:

    一个整数,表示方案数


    题解:

    思路:计数——思考计数类DP。

    既然已经是DP了,考虑设置状态。

    直觉设置:(dp[i][j])表示前i列共有j个连通块的方案数。但是这样没办法转移。

    思考转移:如何能够转移呢?显然,当前面的状态已经算出来的时候,当前状态统计答案肯定要和当前这一列的黑白染色情况有关的。

    也就是说,和当前状态有关。思考状压。

    可以用两位二进制表示当前列的黑白染色情况,分别转移。

    两位?......大可不必状压吧。我们发现,这个状态一共只有4种情况,上黑下白,上白下黑,全黑,全白。

    那直接多开一维存1~4就行,没必要状压。

    转移方程见代码。非常好想。

    初值、答案也见代码:

    #include<cstdio>
    #define int long long
    using namespace std;
    const int mod=998244353;
    int n,k;
    int dp[1010][2010][5];
    //dp[i][j][opt]表示前i列,j个连通块,第i列型号为opt的方案数。
    signed main()
    {
    	scanf("%lld%lld",&n,&k);
    	dp[1][1][3]=dp[1][1][4]=dp[1][2][2]=dp[1][2][1]=1;
    	for(int i=2;i<=n;i++)
    		for(int j=1;j<=k;j++)
    		{
    			dp[i][j][3]=(dp[i-1][j][1]+dp[i-1][j][2]+dp[i-1][j][3]+dp[i-1][j-1][4])%mod;
    			dp[i][j][4]=(dp[i-1][j][1]+dp[i-1][j][2]+dp[i-1][j-1][3]+dp[i-1][j][4])%mod;
    			if(j>1)
    			{
    				dp[i][j][1]=(dp[i-1][j-1][4]+dp[i-1][j][1]+dp[i-1][j-2][2]+dp[i-1][j-1][3])%mod;
    				dp[i][j][2]=(dp[i-1][j-2][1]+dp[i-1][j][2]+dp[i-1][j-1][3]+dp[i-1][j-1][4])%mod;
    			}
    		}
    	int ans=(dp[n][k][1]+dp[n][k][2]+dp[n][k][3]+dp[n][k][4])%mod;
    	printf("%lld",ans);
    	return 0;
    }
    
  • 相关阅读:
    Linux日志分析和管理
    Linux日志分析和管理
    Linux中的网络配置
    Linux中的网络配置
    安全之路 —— C++实现进程守护
    Linux内核升级、GRUB2引导故障处理与密码破解
    Linux内核升级、GRUB2引导故障处理与密码破解
    Linux启动流程和服务管理(init和systemd)
    Linux启动流程和服务管理(init和systemd)
    Linux下逻辑卷LVM的管理和RAID磁盘阵列
  • 原文地址:https://www.cnblogs.com/fusiwei/p/13862111.html
Copyright © 2011-2022 走看看