Time Limit:2000MS Memory Limit:65535K
题型: 编程题 语言: 无限制
RP之神lrc,人称主席,在职业生涯为校队作出过很多贡献,也非常受(人敬仰。 而他之所以为叫做RP之神,是因为在他的一生中发生了许多的人品好的事情,比如 1.曾用随机算法以1/(50^100)概率AC了一道dp题; 2.省赛抽奖现场以1/600概率抽中特等奖获得一个4T的SSD。 因为主席的传神的事迹,使得历届的校队队友都不停膜拜他 膜拜的方式有很多 比如,在你写代码的时候可以加上一句注释 // orz lrc (雾 再比如,拿照片来膜拜(大雾(图片非本人 但是,主席身体越来越差,可能是他最近经常在玩一款叫做te***ing fe**ing的游戏 作为主席的挚友ly,要帮助主席回复一下身体,回复身体当然要做大宝剑啦 但是ly又不是很懂大宝剑,所以来问东莞出身的takio要怎么大宝剑 takio给出了n个大宝剑疗程 每个疗程有个功效 一个疗程只能做一次 每天一定要做三次疗程才有效 所有疗程的功效都是正的 但是,功效太猛不行,功效太弱也不行 所以takio建议每天三个疗程的功效值 x, y, z (x >= y >= z) 要满足 x >= y * p 而且 y >= z * p,p是一个给定的值 因为ly很担心主席的身体,所以ly想做大宝剑越多天越好 但是ly不知道怎么选择才能做最多天 不知道怎么选择主席身体可能就好不起来 身体好不起来就不能玩游戏 不能玩游戏就不能达成全CG 达不成全CG就不能做老司机 不能做老司机takio就不能上车了 想想这是多么严重啊 所以你可以帮ly治好主席的身体,帮takio上车吗
第一行有一个正整数T,表示case数
接下来有2*T行,每两行表示一个case
每个case的第一行有两个数,n和p,表示n个疗程和p
接下来n个数,表示n个疗程的功效
1 <= T <= 1000
1 <= n <= 100
n的范围减小了
0 <= p <= 10000
∑n <= 10000
输出T行 每行1个整数 表示最大的天数
1 3 2 1 2 4
1
思路:
如果有n个疗程,那么最多能大保健n/3天。先进行排序,其中X>=Y>=Z可以说明,要想尽可能做大保健,那么X一定取最大的n/3个数,Z一定取最小的n/3个数。那么Y就是中间的数了。注意的是,如果没办法大保健n/3天,我们就取前n/3-1个数为X,去最后的n/3-1个数为Z,再从中间找Y,以此类推,取前n/3-k和后n/3-k(k=0,1,2……)作为X,Z。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; float Bigsword[105]; int main() { int T; scanf("%d",&T); while(T--) { int i,j,l,k,day=0,s=0; int maxday=0,n; float p; scanf("%d %f",&n,&p); int book[105];//我们用book来记录功效是否已经被用过,因为功效只能用一次 memset(book,0,sizeof(book)); for(i=0;i<n;i++) scanf("%f",&Bigsword[i]); sort(Bigsword,Bigsword+n);//对疗程的功效值进行排序 if(p>=0&&p<=1||n<=2&&&n>=0) { printf("%d\n",n/3);//n<=2和p不大于1的情况,最多只有n/3天 } else { for(k=0;k<=n/3-1;k++) { day=0; for(i=0;i<n/3-k;i++) { if(Bigsword[n-n/3+k+i]>=p*p*Bigsword[i]) { for(j=n/3-k;j<n-n/3+k;j++) { if(book[j]==0&&Bigsword[n-n/3+k+i]>=p*Bigsword[j]&&Bigsword[j]>=p*Bigsword[i]) { day++; book[j]=1;//此时功效已经被使用,记录为1 break; } } } else break; } memset(book,0,sizeof(book)); if(day>maxday) maxday=day; } printf("%d\n",maxday); } } return 0; }