蒟蒻和以前一样还是只能做 $4$ 题, 希望有一天可以 水到 $5$ 题!!
不过也终于上了蓝了。。。
Description
给出$N$个座位, 每个座位上初始有$a_i$ 个人, 这些人都不能移动。
另外还有$M$个人, 要求让他们坐到座位上, $max$ 为所有座位上人数最多 的 人数。
求出 $max$ 的可能最大值和 最小值。
Solution
最大值就是 给出的最多的人数 的座位 加上 $M$
最小值可以二分答案, 容易求出
Code
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define rd read() 5 using namespace std; 6 7 const int N = 1e3; 8 9 int n, m, a[N], maxn; 10 11 int read() { 12 int X = 0, p = 1; char c = getchar(); 13 for(; c > '9' || c < '0'; c = getchar()) if(c == '-') p = -1; 14 for(;c >= '0' && c <= '9'; c = getchar()) X = X * 10 + c - '0'; 15 return X * p; 16 } 17 18 bool jud(int minn) { 19 int rest = m; 20 for(int i = 1; i <= n; ++i) { 21 if(a[i] > minn) return false; 22 rest -= minn - a[i]; 23 } 24 if(rest > 0) return false; 25 else return true; 26 } 27 28 int main() 29 { 30 n = rd; m = rd; 31 for(int i = 1; i <= n; ++i) 32 a[i] = rd; 33 for(int i = 1; i <= n; ++i) 34 maxn = max(maxn, a[i]); 35 int l = 0, r = 2e4 + 5, ans = 0; 36 while(l <= r) { 37 int mid = (l + r) >> 1; 38 if(jud(mid)) r = mid - 1, ans = mid; 39 else l = mid + 1; 40 } 41 printf("%d %d\n", ans, maxn + m); 42 }
B. Vitamins
Description
给出$N$种维生素药, 第$a_i$种药包含了$A,B,C,$中的其中一种或多种维生素, 每一种药都有其价格$cost_i$
现要求出 能吃到维生素 $A,B,C$ 至少花费多少钱。
Solution
显然, 药最多只有7种, 用$2$进制 $S$ 表示是否含有某种维生素, 该种药的最小价格记为 $minn[S]$
在输入时,我们把第 $i$ 种药 更新到对应的 含有维生素的集合S。
求最后的答案时, 只需要三种枚举就行了:
$1$ : 买一种药, 对应集合 $111(B)$
$2$ : 买两种药 $i$ 和 $j$, 并且$i \ | \ j \ = \ 111(B)$
$3$: 买三种药 $i$ 和 $j$, 并且$i \ | \ j \ | \ k \ = \ 111(B)$
求其中的最小值即可。
Code
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 6 const int N = 1e3 + 5; 7 const int inf = ~0U >> 4; 8 9 int n, v[10], minn[10], ans = inf; 10 11 char s[10]; 12 13 struct node { 14 int cost, vis; 15 }a[N]; 16 17 int main() 18 { 19 for(int i = 0; i < 10; ++i) 20 minn[i] = inf; 21 scanf("%d", &n); 22 for(int i = 1; i <= n; ++i) { 23 memset(s, 0,sizeof(s)); 24 memset(v, 0, sizeof(v)); 25 scanf("%d%s", &a[i].cost, s); 26 for(int j = 0, len = strlen(s); j < len; ++j) 27 a[i].vis |= 1 << (s[j] - 'a'); 28 minn[a[i].vis] = min(minn[a[i].vis], a[i].cost); 29 } 30 ans = min(ans, minn[7]); 31 for(int i = 1; i < 8; ++i) 32 for(int j = 1; j < 8; ++j) 33 if((i | j) == 7) ans = min(ans, minn[i] + minn[j]); 34 for(int i = 1; i < 8; ++i) 35 for(int j = 1; j < 8; ++j) 36 for(int k = 1; k < 8; ++k) 37 if((i | j | k) == 7) 38 ans = min(ans, minn[i] + minn[j] + minn[k]); 39 printf("%d\n", ans == inf ? -1 : ans); 40 }