Hello 2018 A - D 题解
2018-01-10 20:12
260 查看
传送门
A, B水题就不说了.
C: 类型 i 的瓶子体积是 2^(i-1),并给出每个瓶子的价钱, 问要得到至少L体积的水最少需要多少钱
首先我们要考虑的就是得到这个i瓶子体积中的水最少需要多少钱. 所以我们前后扫一遍便可得出, 此时我们就有对于每个体积的水我们有了其最少的钱, 那么我们就可以贪心的从大的开始取, 一定是最优的, 然而此时有种情况就是此时瓶子的水直接大于L了, 那么我们取ceil(L/(1<<(i-1)))可能为答案, 还有就是全部恰好组成L也是一种答案, 所以最后我们的答案就是在这些答案中的最小值.
AC Code
D: 现在有n个问题, 考试时间为T, 每道题有难度ai, 以及解决这道题的时间ti, 如果对于没到解决了的题其难度数 >= 总的解题数, 那么就得一分, 问最多可以得多少分.
首先我们考虑, 如果解决一道题, 它并不能使我们的答案变大, 那么这道题也就没有意义. 所以我们考虑有意义的这些题. 假设我们知道最后我们的得分k,那么对于ai >= k, 则就是我们满足的, 所以我们只需要check一下是否有k个这样的问题使得其难度数ai >= k ,当然我们要对解决这些问题的时间从小到大排个序. 如果有的话, 则此时的k就可以作为答案之一. 所以我们当然直接二分答案就行啦, 然后for一遍check一下就行了.
AC Code
A, B水题就不说了.
C: 类型 i 的瓶子体积是 2^(i-1),并给出每个瓶子的价钱, 问要得到至少L体积的水最少需要多少钱
首先我们要考虑的就是得到这个i瓶子体积中的水最少需要多少钱. 所以我们前后扫一遍便可得出, 此时我们就有对于每个体积的水我们有了其最少的钱, 那么我们就可以贪心的从大的开始取, 一定是最优的, 然而此时有种情况就是此时瓶子的水直接大于L了, 那么我们取ceil(L/(1<<(i-1)))可能为答案, 还有就是全部恰好组成L也是一种答案, 所以最后我们的答案就是在这些答案中的最小值.
AC Code
int a[50]; void solve() { int n, L; while(cin >> n >> L) { for (int i = 1 ; i <= n ; i++) cin >> a[i]; for (int i = 1 ; i <= n-1 ; i++) { if (a[i]*2 < a[i+1]) a[i+1] = 2*a[i]; } for (int i = n ; i >= 2 ; i--) { if (a[i] < a[i-1]) a[i-1] = a[i]; } // 得到每个体积的水最少花的钱 ll ans = 0,res = INF; for (int i = n ; i >= 1 ; i--) { ans += 1ll*L/(1 << (i-1))*a[i]; res = min(res, ans + a[i]); // 在这些答案中取一个最小的, L %= (1 << (i-1)); } res = min(res, ans); cout << res << endl; } }
D: 现在有n个问题, 考试时间为T, 每道题有难度ai, 以及解决这道题的时间ti, 如果对于没到解决了的题其难度数 >= 总的解题数, 那么就得一分, 问最多可以得多少分.
首先我们考虑, 如果解决一道题, 它并不能使我们的答案变大, 那么这道题也就没有意义. 所以我们考虑有意义的这些题. 假设我们知道最后我们的得分k,那么对于ai >= k, 则就是我们满足的, 所以我们只需要check一下是否有k个这样的问题使得其难度数ai >= k ,当然我们要对解决这些问题的时间从小到大排个序. 如果有的话, 则此时的k就可以作为答案之一. 所以我们当然直接二分答案就行啦, 然后for一遍check一下就行了.
AC Code
const int maxn = 2e5+5; int cas=1; int n, T; struct node { int a,t,id; bool operator < (const node& x) const { return t < x.t; } }s[maxn]; int res[maxn], cnt = 0; bool check(int x) { cnt = 0; int tot = 0 ; for (int i = 1 ; i <= n ; i++) { if (s[i].a < x) continue; tot += s[i].t; if (tot > T) break; res[++cnt] = s[i].id; } return cnt >= x; } void solve() { while(cin >> n >> T) { for (int i = 1 ; i <= n ; i ++) { int a, b; cin >> a >> b; s[i] = node{a, b, i}; } sort(s+1, s+1+n); int l = 0, r = n , mid, ans = 0; while(r >= l) { mid = (l + r) >> 1; if (check(mid)) { l = mid + 1; ans = mid; } else r = mid - 1; } check(ans); //因为我们每次check使得res数组都在变, 所以最后我们需要答案就应该还要扫一遍. cout << ans << endl << ans << endl; if (!ans) cout << endl; for (int i = 1 ; i <= ans ; i ++) { printf("%d%c", res[i], i == ans ?'\n':' '); } } }
相关文章推荐
- 【Hello 2018 D】Too Easy Problems
- [Codeforces] Hello 2018
- codeforces Hello 2018(A-E)
- Christmas Spruce—codeforces(hello_2018)
- Hello 2018, Bye 2017
- Codeforces Hello 2018 [ABC]
- codeforces Hello 2018 B. Christmas Spruce
- codeforces Hello 2018(A-E)
- Hello 2018(B、C)
- Codeforces Hello 2018 B.Christmas Spruce
- Codeforces Hello 2018
- codeforces Hello 2018(A-E)
- Hello 2018 A
- Hello 2018 C. Party Lemonade (dp好题)
- Codeforces Hello 2018 C. Party Lemonade(思维)
- Codeforces Hello 2018 C. Party Lemonade 贪心、优先队列
- Hello 2018 B
- Codeforces Hello 2018 - A - Modular Exponentiation
- Codeforces Hello 2018 D. Too Easy Problems 二分+贪心
- Codeforces Hello 2018 - B - Christmas Spruce