求助,状压DP 60pts 4 WA
查看原帖
求助,状压DP 60pts 4 WA
119491
5ab_juruo楼主2020/8/29 10:42

rt.

#include <cstdio>
using namespace std;

constexpr int max_n = 12, max_pw = (1 << max_n), mod = 1e8;

int dp[max_n][max_n][max_pw];
bool able[max_n][max_n];

int main()
{
	int n, m, lim, ans = 0;

	scanf("%d%d", &n, &m);
	for (int i = 0; i < n; i++)
		for (int j = 0; j < m; j++)
			scanf("%d", &able[i][j]);
	
	lim = 1 << m;
	
	dp[0][0][0] = 1, dp[0][0][1] = able[0][0];
	for (int i = 1, kt = 2; i < m; i++, kt <<= 1)
		for (int j = 0; j < (kt << 1); j++)
		{
			if (j & kt)
			{
				if (able[0][i] && !(j & (kt>>1)))
					dp[0][i][j] = dp[0][i-1][j&(~kt)];
				else
					dp[0][i][j] = 0;
			}
			else
				dp[0][i][j] = dp[0][i-1][j];
		}
	
	for (int i = 1; i < n; i++)
	{
		for (int j = 0; j < lim; j++)
		{
			if (j & 1)
			{
				if (able[i][0])
					dp[i][0][j] = dp[i-1][n-1][j&(~1)];
				else
					dp[i][0][j] = 0;
			}
			else
				dp[i][0][j] = (dp[i-1][m-1][j] + dp[i-1][m-1][j|1]) % mod;
		}

		for (int j = 1, kt = 1; j < m; j++, kt <<= 1)
			for (int k = 0; k < lim; k++)
			{
				if (k & (kt<<1))
				{
					if (able[i][j] && !(k & kt))
						dp[i][j][k] = dp[i][j-1][k&(~(kt<<1))];
					else
						dp[i][j][k] = 0;
				}
				else
					dp[i][j][k] = (dp[i][j-1][k] + dp[i][j-1][k|(kt<<1)]) % mod;
			}
	}

	for (int i = 0; i < lim; i++)
		ans = (ans + dp[n-1][m-1][i]) % mod;
	printf("%d\n", ans);

	return 0;
}
2020/8/29 10:42
加载中...