标签:bit style 注意 using pac 逆向思维 fine class 通过
本人水平有限,题解不到为处,请多多谅解
本蒟蒻谢谢大家观看
题目:
首先设平均每小时获得的贡献较多的那个为A,另一个为B也就是说比A较划算。那么分两种情况讨论:
若 ,那么直接暴力枚举A用了几次,时间复杂度为O(√n) 。
我们枚举B用了几次,注意B用的次数一定小于A,否则我们可以用b个A替换a个B,得到一种更优的方案。
时间复杂度为O(√n) 。
先说这一段
if(x*b<y*a) swap(x,y),swap(a,b);
是由x/a与y/b比较,为了求单位时间内 A的贡献与B的贡献的大小。这里强制认为 A的贡献较大,所以交换。
接下来是这一段:
LL ans=0; if(a>=n/a){//a>sqrt(n),枚举与A探讨0~n/a次 for(int i=0; i*a<=n; i++) //枚举与好友A探讨i ans=max(ans,i*x+(n-i*a)/b*y); } else{ //a<sqrt(n),枚举与B探讨0~a次,因为若与B次数>=a,则可以把其中a次换成与A的b次一定更优 for(int i=0; i*b<=n&&i<a; i++){ ans=max(ans,i*y+(n-i*b)/a*x); } }
为什么要判断(a>=n/a)呢?通过实测样例可知:如果不特判的话,时间复杂度为O(N),看一下数据也知道会TLE
所以采用节省时间的优化方案,将时间复杂度减至O(√N)。
既然已经使用了优化,那么就有两种情况:
1:直接暴力枚举与A好友探讨时所得到的最大贡献值。
2:采用逆向思维,我们既然已经穷举完A,自然就要枚举B了。注意:在枚举B时,与B好友探讨时间次数必须小于a。如果次数超过a的话,就不是最优解了,因为单位时间B的贡献值小于A的(之前我们已经强制规定),
相当于 一个小的值*一个大的次数+一个大的值*一个小的次数 < 大值*大次数+小值*小次数。已然不是最大值
1 #include <bits/stdc++.h> 2 #define LL long long 3 using namespace std; 4 LL n,x,y,a,b; 5 void init(){ 6 cin>>n>>x>>y>>a>>b; 7 if(x*b<y*a) 8 swap(x,y),swap(a,b); 9 } 10 void work(){ 11 LL ans=0; 12 if(a>=n/a){//a>sqrt(n),枚举与A探讨0~n/a次 13 for(int i=0; i*a<=n; i++) //枚举与好友A探讨i 14 ans=max(ans,i*x+(n-i*a)/b*y); 15 } 16 else{ 17 //a<sqrt(n),枚举与B探讨0~a次,因为若与B次数>=a,则可以把其中a次换成与A的b次一定更优 18 for(int i=0; i*b<=n&&i<a; i++){ 19 ans=max(ans,i*y+(n-i*b)/a*x); 20 } 21 } 22 printf("%lld",ans); 23 } 24 int main() 25 { 26 init(); 27 work(); 28 return 0; 29 } 30 /* 31 10 3 5 2 3 32 10 3(x) 5(y) 2(a) 3(b) 33 10 5(x) 3(y) 3(a) 2(b) 34 */
标签:bit style 注意 using pac 逆向思维 fine class 通过
原文地址:https://www.cnblogs.com/nlyzl/p/11660569.html