一个提示
  • 板块AT_dp_o Matching
  • 楼主incra
  • 当前回复0
  • 已保存回复0
  • 发布时间2023/10/20 08:26
  • 上次更新2023/11/2 12:38:36
查看原帖
一个提示
463956
incra楼主2023/10/20 08:26

对于以下代码为什么能换成最后的代码,我这里给一个解释:

原因:当状态 fi,jf_{i,j} 中 count(j)≠icount (j)\neq i 时,这个状态其实是没用的,所以可以直接把第一位去掉。

代码 11

#include <iostream>
#include <vector>
#include <cstring>
#include <iomanip>
#include <algorithm>
#include <map>
#include <set>
#define x first
#define y second
#define pb push_back
#define desktop "C:\\Users\\incra\\Desktop\\"
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair <int,int> PII;
const int dx[] = {1,-1,0,0},dy[] = {0,0,1,-1};
bool LAST = false;
istream& operator >> (istream& in,char* s) {
    if (LAST) return in;
	char ch = cin.get ();
	while ((isspace (ch) || ch == '\n') && ch != EOF) ch = cin.get ();
	int n = 0;
	while (!(isspace (ch) || ch == '\n') && ch != EOF) s[n++] = ch,ch = cin.get ();
	s[n] = '\0';
	if (ch == EOF) LAST = true;
	return in;
}
template <typename T1,typename T2> bool tomax (T1 &x,T2 y) {
	if (y > x) return x = y,true;
	return false;
}
template <typename T1,typename T2> bool tomin (T1 &x,T2 y) {
	if (y < x) return x = y,true;
	return false;
}
LL power (LL a,LL b,LL p) {
	LL ans = 1;
	while (b) {
		if (b & 1) ans = ans * a % p;
		a = a * a % p;
		b >>= 1;
	}
	return ans;
}
const int N = 25,M = 1 << 21,MOD = 1e9 + 7;
int n;
vector <int> g[N];
LL f[N][M];
int main () {
	cin >> n;
	for (int i = 1;i <= n;i++) {
		for (int j = 1;j <= n;j++) {
			int x;
			cin >> x;
			if (x) g[i].push_back (j);
		}
	}
	f[0][0] = 1;
	for (int i = 1;i <= n;i++) {
		for (int j = 0;j < (1 << n) - 1;j++) {
			for (int k : g[i]) {
				if (j >> k - 1 & 1) continue;
				int nj = j | (1 << k - 1);
				f[i][nj] = (f[i][nj] + f[i - 1][j]) % MOD;
			}
		}
	}
	LL ans = 0;
	for (int i = 0;i < 1 << n;i++) ans = (ans + f[n][i]) % MOD;
	cout << ans << endl;
	return 0;
}

代码 22

#include <iostream>
#include <vector>
#include <cstring>
#include <iomanip>
#include <algorithm>
#include <map>
#include <set>
#define x first
#define y second
#define pb push_back
#define desktop "C:\\Users\\incra\\Desktop\\"
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair <int,int> PII;
const int dx[] = {1,-1,0,0},dy[] = {0,0,1,-1};
bool LAST = false;
istream& operator >> (istream& in,char* s) {
    if (LAST) return in;
	char ch = cin.get ();
	while ((isspace (ch) || ch == '\n') && ch != EOF) ch = cin.get ();
	int n = 0;
	while (!(isspace (ch) || ch == '\n') && ch != EOF) s[n++] = ch,ch = cin.get ();
	s[n] = '\0';
	if (ch == EOF) LAST = true;
	return in;
}
template <typename T1,typename T2> bool tomax (T1 &x,T2 y) {
	if (y > x) return x = y,true;
	return false;
}
template <typename T1,typename T2> bool tomin (T1 &x,T2 y) {
	if (y < x) return x = y,true;
	return false;
}
LL power (LL a,LL b,LL p) {
	LL ans = 1;
	while (b) {
		if (b & 1) ans = ans * a % p;
		a = a * a % p;
		b >>= 1;
	}
	return ans;
}
const int N = 25,M = 1 << 21,MOD = 1e9 + 7;
int n;
vector <int> g[N];
LL f[M];
int count (int x) {
	int ans = 0;
	while (x) ans += x & 1,x >>= 1;
	return ans;
}
int main () {
	cin >> n;
	for (int i = 1;i <= n;i++) {
		for (int j = 1;j <= n;j++) {
			int x;
			cin >> x;
			if (x) g[i].push_back (j);
		}
	}
	f[0] = 1;
	for (int i = 0;i < (1 << n) - 1;i++) {
		int j = count (i) + 1;
		for (int k : g[j]) {
			if (i >> k - 1 & 1) continue;
			int ni = i | (1 << k - 1);
			f[ni] = (f[ni] + f[i]) % MOD;
		}
	}
	cout << f[(1 << n) - 1] << endl;
	return 0;
}
2023/10/20 08:26
加载中...