NOIP2018提高组省一冲奖班模测训练(三)
自己按照noip的方式考,只在最后一两分钟交了一次
第一题过了,对拍拍到尾。
第二题不会。考试时往组合计数的方向想,推公式,推了一个多小时,大脑爆炸,还是一直推不出来(然而正解是dp??)
第三题打了暴力
如果是正式比赛的话,就在省一分数线徘徊。
第二题如果能拿一点部分分的话,那省一就比较稳了
正式比赛的话应该部分分会有,这套题的第二题部分分貌似拿不了
讲解讲的非常细,非常清晰。比雅礼集训听的舒服太多太多了。
Anan的派对
Anan想举办一个派对。
Anan的朋友总共有
n 人。第i个人如果参加派对会得到 ci 的快乐值,除他自己外每多一个人参加他会减少 di 的快乐值。
Anan想让这个派对的总快乐值尽可能大,在这个基础上,能来的人越多越好。
Anan想知道最佳的邀请方案的快乐值与参加人数。
对于
50% 的数据, n≤20
对于 100% 的数据, n≤1000
对于 100% 的数据, n≤1000
Input
第一行一个正整数n 。 第二行n个整数表示ci。 第三行n个整数表示di。
Output
第一行一个整数最大快乐值。 第二行一个整数表示最佳方案的参加人数。
Input示例
6 10 10 10 10 10 9 2 2 2 2 2 3
Output示例
18 3
1000的数据范围一般是n方,最多加两个log
这道题第一反应二分参加人数不就非常好算了吗
但是貌似参加人数不满足单调性
然后这个思路就pass掉了
然后开始绕弯子,想到搜索,想到动规……
一直绕了40多分钟……
然后突然想到,貌似直接枚举人数复杂度是n方logn的
…………
相信自己的第一感觉……
然后不要凭感觉看会不会超时,要算复杂度……
最后1个小时才AC了,排行榜上有人17分钟AC了……
枚举出人数之后,有两个小优化(不加也能过)
(1)排序的复杂度是nlogn,而我们关心的只是前几个人的值,所以可以用nth_element
复杂度是O(n)的。
可以把n方logn 优化到n方
(2)如果有人的值是负数可以直接break,这个人不选还更优
#include<bits/stdc++.h> #define REP(i, a, b) for(register int i = (a); i < (b); i++) #define _for(i, a, b) for(register int i = (a); i <= (b); i++) using namespace std; const int MAXN = 1e3 + 10; int c[MAXN], d[MAXN], t[MAXN], n; int main() { scanf("%d", &n); _for(i, 1, n) scanf("%d", &c[i]); _for(i, 1, n) scanf("%d", &d[i]); int ans1 = 0, ans2 = 0; _for(num, 1, n) { _for(i, 1, n) t[i] = c[i] - d[i] * (num - 1); nth_element(t + 1, t + num, t + n + 1, greater<int>()); int sum = 0, ok = 1; _for(i, 1, num) { sum += t[i]; if(t[i] < 0) { ok = 0; break; } } if(!ok) break; if(ans1 < sum) { ans1 = sum; ans2 = num;} else if(ans1 == sum && ans2 < num) ans2 = num; } printf("%d\n%d\n", ans1, ans2); return 0; }
扫描二维码关注公众号,回复:
3755506 查看本文章