好吧,题目大概意思就是找x轴上找到一个点,使得这个点到其他点的距离乘以权值最小,网上的那种做法我还要思考一下。。。这题就先用三分做掉好了
精度写成了.4f过了,但是.5fWA,。。还是要注意一下。。这个题目和HDU 4355 很像 这里给出4355 的链接 http://acm.hdu.edu.cn/showproblem.php?pid=4355
这两个题目是一样的。。至少我用的方法是一样的,都可以通过三分来解决。
三分是用来求解单峰函数的极值的,就拿这个题目的来说,我们可以构造出一个函数F(X)来描述这一点的不满意度,显然F(X)=∑fabs(X-index)*weigh,其中 index表示下标,weigh表示权值,求和便是总的不满意度。其实我们可以单看一项,fabs(X-index)*weigh这个函数在坐标系上是一个凹函数,那么根据有限个凹函数的和仍然是凹函数这个定理我们可以推知F(X)也是凹函数,凹函数是一种单峰函数,因此F(X)是单峰函数,因此这道题目可以用三分法来求解,只是写三分的时候需要注意一下边界的移动情况,不过那都是细节了,下面给出SGU 114 的代码:
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
int n;
double up,down=0x3f3f3f3f,mid1,mid2,dis1,dis2;
struct Node{
double index,wi;
}arr[15010];
int main(){
while(scanf("%d",&n)!=EOF){
for(int i=0;i<n;++i)
scanf("%lf%lf",&arr[i].index,&arr[i].wi),up=max(up,arr[i].index),down=min(down,arr[i].index);
while(up-down>=1E-5){
dis1=dis2=0;
mid1=(up+down)/2,mid2=(mid1+up)/2;
for(int i=0;i<n;++i)
dis1+=fabs(mid1-arr[i].index)*arr[i].wi,dis2+=fabs(mid2-arr[i].index)*arr[i].wi;
(dis1<dis2)?up=mid2:down=mid1;
//printf("%lf %lf\n",dis1,dis2);
}
printf("%.4lf\n",up);up=0,down=0x3f3f3f3f;
}
return 0;
}
接下来是HDU 4355
这道题目的函数F(X)=∑fabs(X-index)*weigh^3,其实说假若不考虑极值点恰好在端点的情况的时候,是可以求导的,当然了,必须取定X∈(ai,a(i+1))这样的一个开区间里面,然后就可以去掉绝对值符号,求导数就看出来二阶导数是大于0的,然后就可以知道这个函数是凹函数,然后就可以知道这个函数是单峰函数了,代码同上面的差不多
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<climits>
using namespace std;
int t,n,times=1;
double s[50010],w[50010],mid1,mid2,te1,te2,up,down,ans=1E+200,maxm,minm=1E+200;
int main(){
scanf("%d",&t);
while(t--){
scanf("%d",&n);
for(int i=0;i<n;++i)
scanf("%lf%lf",&s[i],&w[i]),maxm=max(maxm,s[i]),minm=min(minm,s[i]);
up=maxm,down=minm;
while(up-down>=1E-5){
te1=te2=0;
mid1=(up+down)/2;
mid2=(mid1+up)/2;
for(int i=0;i<n;++i){
te1+=pow(fabs(mid1-s[i]),3)*w[i],te2+=pow(fabs(mid2-s[i]),3)*w[i];
}
if(te1>ans&&te2>ans){
down=mid1,up=mid2;
}
else if(te1>te2){
ans=min(te2,ans);
down=mid1;
}
else{
ans=min(te1,ans);
up=mid2;
}
}
printf("Case #%d: %d\n",times,(long long)floor(ans+0.5));ans=1E+200;++times;maxm=0,minm=1E+200;
}
return 0;
}