1. 题目来源
链接:3646. 分水果
2. 题目解析
很明显,答案不会超过 7,且每种小朋友拿到手的水果状态是确定的。所以,可以直接暴力枚举 7 种情况,每种情况有选、不选两种情况,总共是 2^7
种情况。判断每种情况下用的水果数量,如果没有大于给定水果的话,该状态合法,更新一下答案即可。
很经典的二进制枚举:
#include <bits/stdc++.h>
using namespace std;
int s[7][3] = {
{0, 0, 1},
{0, 1, 0},
{0, 1, 1},
{1, 0, 0},
{1, 0, 1},
{1, 1, 0},
{1, 1, 1},
};
int main() {
int T;
scanf("%d", &T);
while (T -- ) {
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
int res = 0;
for (int i = 0; i < 1 << 7; i ++ ) {
int sa = 0, sb = 0, sc = 0, cnt = 0;
for (int j = 0; j < 7; j ++ ) {
if (i >> j & 1) {
sa += s[j][0];
sb += s[j][1];
sc += s[j][2];
cnt ++ ;
}
}
if (sa <= a && sb <= b && sc <= c) res = max(res, cnt);
}
printf("%d\n", res);
}
return 0;
}
时间复杂度: O ( 2 7 × 7 ) O(2^7 \times 7) O(27×7)
空间复杂度: O ( 1 ) O(1) O(1)
还有一种直接来构造答案:
- 自己能单独成为一种,则自己单独成为一种情况
- 和其他水果搭配的时候尽量找最大和最小的配对
其实也就分了三步,先搞定 1 个 1 的 3 个,再搞定 2 个 1 的 3 个,最后搞定 3 个 1 的 1 个。
/*
001 1
010 2
100 3
011 4
101 5
110 6
111 7
*/
#include <bits/stdc++.h>
using namespace std;
int a[3];
int main() {
int T;
scanf("%d", &T);
while (T -- ) {
scanf("%d%d%d", &a[0], &a[1], &a[2]);
sort(a, a + 3);
int res = 0;
if (a[0]) res ++ , a[0] -- ;
if (a[1]) res ++ , a[1] -- ;
if (a[2]) res ++ , a[2] -- ;
if (a[2] && a[0]) res ++ , a[2] -- , a[0] -- ;
if (a[2] && a[1]) res ++ , a[2] -- , a[1] -- ;
if (a[1] && a[0]) res ++ , a[1] -- , a[0] -- ;
if (a[2] && a[1] && a[0]) res ++ ;
printf("%d\n", res);
}
return 0;
}
时间复杂度:
O
(
1
)
O(1)
O(1)
空间复杂度:
O
(
1
)
O(1)
O(1)