[关闭]
@sensitive-cs 2017-03-17T09:09:25.000000Z 字数 2523 阅读 735

CQUPT 二分

题解


HDU:2899 STRANGE FUNCTION
题意:
求一个函数在自变量处于0到100闭区间时候的最小值。
思路:
经过求导发现,此函数的二阶导数在定义域内恒大于0,则一阶导数单调递增,又因为在0和100这两个端点一阶导数的值肯定是异号的,所以一阶导数在定义域内有一个零点,原函数在定义域内有一个极小值点也是最小值点。最后就用二分不断逼近此点(一阶导数),达到精度的后几位就ok。
代码:

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. double y;
  4. double f1x(double t)
  5. {
  6. return (42 * pow(t,6) + 48 * pow(t,5) + 21 * pow(t,2) + 10 * t - y);
  7. }
  8. int main()
  9. {
  10. int t;
  11. scanf("%d",&t);
  12. while (t--)
  13. {
  14. scanf("%lf",&y);
  15. double x1 = 0,x2 = 100;
  16. while (fabs(f1x((x1 + x2)/2)) > 1e-8)
  17. {
  18. if (f1x(x1) * f1x((x1 + x2)/2) < 0)
  19. x2 = (x1 + x2)/2;
  20. else
  21. x1 = (x1 + x2)/2;
  22. }
  23. double tmp = (x1 + x2)/2;
  24. double res = 6 * pow(tmp,7) + 8 * pow(tmp,6) + 7 * pow(tmp,3) + 5 * pow(tmp,2) - y * tmp;
  25. printf("%.4f\n",res);
  26. }
  27. return 0;
  28. }

HDU 2141 : CAN YOU FIND IT
题意:
给出三个数组,和一个数X,问是否能在3个数组中分别找到一个数,使得三个数相加等于X。
思路:
二分的一点小变化,即复杂度的改进,先把A,B数组的和存入一个新数组,对于每一个X-Ci,用二分法在新数组中寻找是否存在这样的一个数。
代码:

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. int a[505];
  4. int b[505];
  5. int c[505];
  6. int ab[255025];
  7. int x[1005];
  8. int myfind(int t,int edge)
  9. {
  10. int left = 0,right = edge - 1;
  11. while (left <= right)
  12. {
  13. int mid = (left + right) / 2;
  14. if (ab[mid] == t)
  15. return 1;
  16. else if (ab[mid] > t)
  17. right = mid - 1;
  18. else
  19. left = mid + 1;
  20. }
  21. return 0;
  22. }
  23. int main()
  24. {
  25. int l,n,m,s;
  26. int cnt = 1;
  27. while(scanf("%d%d%d",&l,&n,&m) == 3)
  28. {
  29. int h = 0;
  30. for (int i = 0;i < l;i++)
  31. scanf("%d",&a[i]);
  32. for (int i = 0;i < n;i++)
  33. scanf("%d",&b[i]);
  34. for (int i = 0;i < m;i++)
  35. scanf("%d",&c[i]);
  36. scanf("%d",&s);
  37. for (int i = 0;i < s;i++)
  38. scanf("%d",&x[i]);
  39. sort(a,a+l);
  40. sort(b,b+n);
  41. sort(c,c+m);
  42. printf("Case %d:\n",cnt++);
  43. for (int i = 0;i < l;i++)
  44. for (int j = 0;j < n;j++)
  45. ab[h++] = a[i] + b[j];
  46. sort(ab,ab+h);
  47. for (int i = 0;i < s;i++)
  48. {
  49. int flag = 0;
  50. for (int j = 0;j < m;j++)
  51. {
  52. int tmp = x[i] - c[j];
  53. if (myfind(tmp,h))
  54. flag = 1;
  55. }
  56. if (flag)
  57. printf("YES\n");
  58. else
  59. printf("NO\n");
  60. }
  61. }
  62. return 0;
  63. }

POJ 3273 : MONTHLY EXPENSE
题意:
给出n个数,要求把这n个数分成m个部分,使得每个部分的数的和的最大值最小。
思路:
二分+贪心,套路。
代码:

  1. #include <stdio.h>
  2. int n,m;
  3. int cost[100010];
  4. int solve(int money)
  5. {
  6. int tmp = 0,_if = 1;
  7. for (int i = 0;i < n;i++)
  8. {
  9. if (tmp + cost[i] <= money) tmp += cost[i];
  10. else
  11. {
  12. tmp = 0;
  13. _if++;
  14. i--;
  15. }
  16. }
  17. return _if <= m;
  18. }
  19. int main()
  20. {
  21. scanf("%d%d",&n,&m);
  22. for (int i = 0;i < n;i++)
  23. scanf("%d",&cost[i]);
  24. int lb = -1,ub = 0;
  25. for (int i = 0;i < n;i++)
  26. {
  27. if (cost[i] > lb)
  28. lb = cost[i];
  29. ub += cost[i];
  30. }
  31. while(lb < ub)
  32. {
  33. int mid = (lb + ub) / 2;
  34. if (solve(mid)) ub = mid;
  35. else lb = mid + 1;
  36. }
  37. printf("%d\n",ub);
  38. return 0;
  39. }

poj3258 river hopscotch
题意:
最大化最小值。有n个石头,两个岸,问可以移走m个石头的情况下两个障碍物之间距离最小的最大值是多少。
思路:
二分。QAQ我只能把这题记住了。
代码:

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <algorithm>
  4. using namespace std;
  5. int a[50005];
  6. int m,n,L;
  7. int meet(int dis)
  8. {
  9. int cnt = 0;
  10. int last = 0;
  11. for (int i = 1;i <= n+1;i++)
  12. {
  13. if (dis >= (a[i]-a[last]))
  14. {
  15. cnt++;
  16. }
  17. else
  18. {
  19. last = i;
  20. }
  21. }
  22. return cnt;
  23. }
  24. int main()
  25. {
  26. scanf("%d%d%d",&L,&n,&m);
  27. a[0] = 0;
  28. for (int i = 1;i <= n;i++)
  29. scanf("%d",&a[i]);
  30. a[n+1] = L;
  31. sort(a+1,a+n+1);
  32. int low = 0,high = L;
  33. while (low <= high)
  34. {
  35. int mid = (low + high) >> 1;
  36. if (meet(mid) <= m) low = mid + 1;
  37. else high = mid - 1;
  38. }
  39. printf("%d\n",low);
  40. return 0;
  41. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注