hdu 4665 (dfs / 2-SAT)

題目鏈接


多校第六場的題目, 比賽時沒什麼想法, 後來看GYZ神犇的解題報告裏用的是O(n ^ 2)的2 - SAT解法, 但本弱菜還是沒想到如何構圖, 後來看別人都是用dfs過的, 自己寫了一版覺得還是挺好寫的, 而且速度也很快, 但複雜度不知如何分析, 一開始覺得dfs應該會T的, 畢竟需要遞歸2000層, 後來想了想覺得這題有一定的特殊性, 因爲題目只要求輸出一組解, 而且如果相同同種顏色很多的話解的個數也會多, 所以dfs速度會比較快, 但準確的理論複雜度還是不知如何分析, 有時間再研究2-SAT解法吧。。。。。


#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <cctype>
#include <set>
#include <deque>
#include <map>

using namespace std;

inline int readint() {
	char c = getchar();
	while (!isdigit(c)) c = getchar();

	int x = 0;
	while (isdigit(c)) {
		x = x * 10 + c - '0';
		c = getchar();
	}

	return x;
}

int buf[10];

inline void writeint(int x) {
	int p = 0;
	if (x == 0) p++;
	else while (x) {
		buf[p++] = x % 10;
		x /= 10;
	}
	for (int j = p - 1; j >= 0; j--)
		putchar('0' + buf[j]);
}

const int N = 2005;
int cnt0[N], cnt1[N], sum[N];
int res[N], s0[N], s1[N], str[N];
int n;
bool ok = 0;

void dfs(int id, int sz0, int sz1) {
	if (id == n + 1) {
		for (int i = 1; i <= n; i++) 
			printf("%d", res[i]);
		puts("");	
		ok = 1;
		return;
	}

	if (cnt0[str[id]] < sum[str[id]] / 2 && (sz0 >= sz1 || str[id] == s1[sz0])) {
		res[id] = 0;
		cnt0[str[id]]++;
		s0[sz0] = str[id];
		dfs(id + 1, sz0 + 1, sz1);
		if (ok) return;
		cnt0[str[id]]--;
	}

	
	if (cnt1[str[id]] < sum[str[id]] / 2 && (sz1 >= sz0 || str[id] == s0[sz1])) {

		res[id] = 1;
		cnt1[str[id]]++;
		s1[sz1] = str[id];
		dfs(id + 1, sz0, sz1 + 1);	
		if (ok) return;
		cnt1[str[id]]--;
	}

}

int main() {
	int test;
	test = readint();
	while (test--) {
		n = readint();
		for (int i = 1; i <= n; i++)
			cnt0[i] = 0, cnt1[i] = 0, sum[i] = 0;

		for (int i = 1; i <= n; i++)
			str[i] = readint(), sum[str[i]]++;

		ok = 0;

		s0[1] = str[1];
		cnt0[str[1]]++;
		dfs(2, 2, 1);	
		
	}
	return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章