NOIP2018提高组省一冲奖班模测训练(三)

NOIP2018提高组省一冲奖班模测训练(三)

自己按照noip的方式考,只在最后一两分钟交了一次

第一题过了,对拍拍到尾。

第二题不会。考试时往组合计数的方向想,推公式,推了一个多小时,大脑爆炸,还是一直推不出来(然而正解是dp??)

第三题打了暴力

如果是正式比赛的话,就在省一分数线徘徊。

第二题如果能拿一点部分分的话,那省一就比较稳了

正式比赛的话应该部分分会有,这套题的第二题部分分貌似拿不了

讲解讲的非常细,非常清晰。比雅礼集训听的舒服太多太多了。

Anan的派对 

Anan想举办一个派对。
Anan的朋友总共有  n 人。第i个人如果参加派对会得到 ci 的快乐值,除他自己外每多一个人参加他会减少 di 的快乐值。
Anan想让这个派对的总快乐值尽可能大,在这个基础上,能来的人越多越好。
Anan想知道最佳的邀请方案的快乐值与参加人数。
对于  50% 的数据, n20 
对于 100% 的数据, n1000 
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;
}
 
   
  






猜你喜欢

转载自www.cnblogs.com/sugewud/p/9863668.html