题目抽象:给你一些数据,给你公式(不是简单公式),求最小值。
分析:公式都给出了,又是求最值,很自然的想法是二分,或者三分。这题显然不是二分。那么就是三分了。已水量为变量,那么化肥的量的最小值就可以求出。比赛的时候虽然不能证明该函数为吐函数,但是很容易猜想到是三分。
1 /******************************** 2 please don‘t hack me!! /(ToT)/~~ 3 __------__ 4 /~ ~ 5 | //^\\//^\| 6 /~~\ || T| |T|:~ 7 | |6 ||___|_|_||:| 8 \__. / o \/‘ 9 | ( O ) 10 /~~~~\ `\ \ / 11 | |~~\ | ) ~------~`12 /‘ | | | / ____ /~~~)13 (_/‘ | | | /‘ | ( | 14 | | | \ / __)/ 15 \ \ \ \/ /‘ \ `16 \ \|\ / | |\___| 17 \ | \____/ | | 18 /^~> \ _/ < 19 | | \ 20 | | \ \ 21 -^-\ \ | ) 22 `\_______/^\______/ 23 ************************************/ 24 25 #include <iostream> 26 #include <cstdio> 27 #include <cstring> 28 #include <cmath> 29 #include <algorithm> 30 #include <string> 31 #include <vector> 32 #include <set> 33 #include <map> 34 #include <queue> 35 #include <stack> 36 #include <cstdlib> 37 #include <sstream> 38 using namespace std; 39 typedef long long LL; 40 const LL INF = 0x5fffffff; 41 const double EXP = 1E-8; 42 const LL MOD = (LL)1E9+7; 43 const int MS = 100005; 44 45 struct node { 46 double vw,pf,vf,th; 47 }nodes[MS]; 48 49 int main() { 50 int T, N; 51 double pw; 52 while (scanf("%d",&N) == 1) { 53 if (N == 0) 54 break; 55 scanf("%lf",&pw); 56 for (int i = 0; i < N; i++) { 57 scanf("%lf%lf%lf%lf",&nodes[i].vw,&nodes[i].pf,&nodes[i].vf,&nodes[i].th); 58 } 59 double l = 0; //枚举水量 60 double r = 101; 61 double sum1, sum2; 62 // 用三分的次数代替浮点数的比较。 63 for (int time = 1; time < 200; time++) { 64 double mid = l + (r - l) / 3; 65 double mmid = r - (r - l) / 3; 66 sum1 = mid * pw; 67 sum2 = mmid * pw; 68 for (int i = 0; i< N;i++) { 69 double t = nodes[i].th - mid * nodes[i].vw; 70 if(t <= 0) 71 continue; 72 sum1 += t / nodes[i].vf * nodes[i].pf; 73 } 74 for (int i = 0; i< N;i++) { 75 double t = nodes[i].th - mmid * nodes[i].vw; 76 if(t <= 0) 77 continue; 78 sum2 += t / nodes[i].vf * nodes[i].pf; 79 } 80 if (sum1 > sum2) 81 l = mid; 82 else 83 r = mmid; 84 } 85 printf("%.5lf\n",sum1); 86 } 87 return 0; 88 }
时间: 2024-10-08 04:20:08