@lawk97
2017-04-20T00:28:08.000000Z
字数 5731
阅读 1135
专题
二分
三分
#include <cstdio>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <string>
using namespace std;
double fun1(double x,double y)
{
return 6*x*x*x*x*x*x*x+8*x*x*x*x*x*x+7*x*x*x+5*x*x-y*x;
}
double fun2(double x,double y)
{
return 42*x*x*x*x*x*x+48*x*x*x*x*x+21*x*x+10*x-y;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
double y;
scanf("%lf",&y);
double l=0,r=100;
while(r-l>1e-8)
{
double m=l+(r-l)/2;
if(fun2(m,y)<=0)
l=m;
else
r=m;
}
printf("%.4f\n",fun1(l, y));
}
return 0;
}
#include <cstdio>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <string>
using namespace std;
long long a[505],b[505],c[505];
long long ab[250005];
int main()
{
int L,M,N;
int kase=0;
while(~scanf("%d%d%d",&L,&M,&N))
{
for(int i=0;i<L;i++)
scanf("%lld",&a[i]);
for(int i=0;i<M;i++)
scanf("%lld",&b[i]);
for(int i=0;i<N;i++)
scanf("%lld",&c[i]);
for(int i=0;i<L;i++)
for(int j=0;j<M;j++)
ab[i*M+j]=a[i]+b[j];
sort(ab, ab+L*M );
int s;
scanf("%d",&s);
printf("Case %d:\n",++kase);
while(s--)
{
long long key;
scanf("%lld",&key);
int flag=0;
for(int i=0;i<N;i++)
{
int l=0,r=L*M;
long long k=key-c[i];
while(r-l>1)
{
int m=l+(r-l)/2;
if(ab[m]<=k)
l=m;
else
r=m;
}
if(ab[l]==k)
{
flag=1;
break;
}
}
if(flag)
printf("YES\n");
else
printf("NO\n");
}
}
return 0;
}
思路
所求最小限度必然在一个特定的区间内,这个区间的最小值为花费最多的那一天的花费,最大值为所有天的花费之和。可对这个区间进行二分查找。
如果当前找的限度为K,那么以K为限度进行分组,若组数大于M,则说明K值小了;如果组数小于M,则说明K值大了。
需要注意的是,所求解显然是唯一的。意思是即便组数等于M,当前的K也不一定为最小限度,应继续查找直到循环结束。
另附在网上看到的很棒的一个题解
AC代码
#include <cstdio>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <string>
using namespace std;
int n,m,sum,ma;
int a[100005];
int arr(int x)
{
int sx=0,num=1;
for(int i=0;i<n;i++)
{
sx+=a[i];
if(sx>x)
{
sx=a[i];
num++;
}
}
return num;
}
int main()
{
scanf("%d%d",&n,&m);
scanf("%d",&a[0]);
sum=a[0];
ma=a[0];
for(int i=1;i<n;i++)
{
scanf("%d",&a[i]);
sum+=a[i];
if(ma<a[i])
ma=a[i];
}
int l=ma,r=sum;
while(l<r)
{
int mid=l+(r-l)/2;
if(arr(mid)<=m)
r=mid-1;
else
l=mid+1;
}
printf("%d\n",l);
return 0;
}
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
int main(){
int l,n,m,le,ri;
int dis[50005];
scanf("%d%d%d",&l,&n,&m);
dis[0]=0;
dis[n+1]=l;
le=l;
ri=l;
for(int i=1;i<=n;i++){
scanf("%d",&dis[i]);
}
sort(dis,dis+n+2);//按石头的原始位置排列
for(int i=1;i<=n+1;i++){
if (dis[i]-dis[i-1]<le)
{
le=dis[i]-dis[i-1];
}
}
while(le<ri){
int sum=0,mid=le+(ri-le)/2,count=0;
for (int i = 1; i <= n+1; ++i)//到n+1是为了对最后一段进行处理
{
sum+=dis[i]-dis[i-1];
if (sum<=mid)//why <= ??感觉是因为贪心算法
{
count++;
}else{
sum=0;
}
}
if(count<=m){
le=mid+1;
}else{
ri=mid;
}
}
printf("%d\n",le);
return 0;
}
[POJ - 1018]
We have received an order from Pizoor Communications Inc. for a
special communication system. The system consists of several devices.
For each device, we are free to choose from several manufacturers.
Same devices from two manufacturers differ in their maximum bandwidths
and prices. By overall bandwidth (B) we mean the minimum of the
bandwidths of the chosen devices in the communication system and the
total price (P) is the sum of the prices of all chosen devices. Our
goal is to choose a manufacturer for each device to maximize B/P.
Input
The first line of the input file contains a single integer t (1 ≤ t ≤
10), the number of test cases, followed by the input data for each
test case. Each test case starts with a line containing a single
integer n (1 ≤ n ≤ 100), the number of devices in the communication
system, followed by n lines in the following format: the i-th line (1
≤ i ≤ n) starts with mi (1 ≤ mi ≤ 100), the number of manufacturers
for the i-th device, followed by mi pairs of positive integers in the
same line, each indicating the bandwidth and the price of the device
respectively, corresponding to a manufacturer. Output Your program
should produce a single line for each test case containing a single
number which is the maximum possible B/P for the test case. Round the
numbers in the output to 3 digits after decimal point.
Sample Input
1 3
3 100 25 150 35 80 25
2 120 80 155 40
2 100 100 120 110
Sample Output
0.649
[ZOJ - 3203]
Compared to wildleopard's wealthiness, his brother mildleopard is
rather poor. His house is narrow and he has only one light bulb in his
house. Every night, he is wandering in his incommodious house,
thinking of how to earn more money. One day, he found that the length
of his shadow was changing from time to time while walking between the
light bulb and the wall of his house. A sudden thought ran through his
mind and he wanted to know the maximum length of his shadow.
Input
The first line of the input contains an integer T (T <= 100),
indicating the number of cases.Each test case contains three real numbers H, h and D in one line. H
is the height of the light bulb while h is the height of mildleopard.
D is distance between the light bulb and the wall. All numbers are in
range from 10-2 to 103, both inclusive, and H - h >= 10-2.
Output
For each test case, output the maximum length of mildleopard's shadow
in one line, accurate up to three decimal places..
Sample Input
3
2 1 0.5
2 0.5 3
4 3 4
Sample Output
1.000
0.750
4.000