天天看點

UVa 11218 KTV (枚舉&位運算)

11218 - KTV

Time limit: 3.000 seconds 

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=112&page=show_problem&problem=2159

One song is extremely popular recently, so you and your friends decided to sing it in KTV. The song has 3 characters, so exactly 3 people should sing together each time (yes, there are 3 microphones in the room). There are exactly 9 people, so you decided that each person sings exactly once. In other words, all the people are divided into 3 disjoint groups, so that every person is in exactly one group.

UVa 11218 KTV (枚舉&位運算)

However, some people don't want to sing with some other people, and some combinations perform worse than others combinations. Given a score for every possible combination of 3 people, what is the largest possible score for all the 3 groups?

Input

The input consists of at most 1000 test cases. Each case begins with a line containing a single integer n (0 < n < 81), the number of possible combinations. The next n lines each contains 4 positive integers a, b, c, s (1 <= a < b < c <= 9, 0 < s < 10000), that means a score of s is given to the combination ( a, b, c). The last case is followed by a single zero, which should not be processed.

Output

For each test case, print the case number and the largest score. If it is impossible, print -1.

Sample Input

3
1 2 3 1
4 5 6 2
7 8 9 3
4
1 2 3 1
1 4 5 2
1 6 7 3
1 8 9 4
0
      

Output for the Sample Input

Case 1: 6
Case 2: -1
      

O(n^3)枚舉所有可能的情況并取最大值。

注意用位運算加快速度。

完整代碼:

/*0.049s*/

#include<bits/stdc++.h>
using namespace std;

int c[85], s[85], tmp, n, i, j, k, ans;

int solve()
{
	if (n < 3) return -1;
	ans = -1;
	for (i = 0; i < n - 2; ++i)
	{
		tmp = c[i];
		for (j = i + 1; j < n - 1; ++j)
		{
			if ((c[i] & c[j]) == 0)
			{
				c[i] |= c[j];
				for (k = j + 1; k < n; ++k)
				{
					if ((c[i] & c[k]) == 0)
						ans = max(ans, s[i] + s[j] + s[k]);
				}
				c[i] = tmp; ///c[i]複原
			}
		}
	}
	return ans;
}

int main()
{
	int a1, a2, a3, cas = 0;
	while (scanf("%d", &n), n)
	{
		for (i = 0; i < n; ++i)
		{
			scanf("%d%d%d%d", &a1, &a2, &a3, &s[i]);
			c[i] = (1 << a1) | (1 << a2) | (1 << a3);
		}
		printf("Case %d: %d\n", ++cas, solve());
	}
	return 0;
}