51Nod - 1110
X轴上有N个点,每个点除了包括一个位置数据Xi,还包括一个权值Wi。点P到点Pi的带权距离 = 实际距离 * Pi
的权值。求X轴上一点使它到这N个点的带权距离之和最小,输出这个最小的带权距离之和。
第2 - N + 1行:每行2个数,中间用空格分隔,分别是点的位置及权值。(-10^5 <= X i <= 10^5,1 <= W i <= 10^5) Output 输出最小的带权距离之和。 Sample Input
5 -1 1 -3 1 0 1 7 1 9 1Sample Output
20
代码1:
爆搜...就是想把这个范围假设成0~~~2*1e5...然后假设起点在0的时候.....之后一步一步的往右边走到尽头.找出其中一个最小的哪一个
代码:这个是参考学长的(就是不小心就搜到了学长的)..... 网址是这个
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5;
ll sum[2*maxn+100];
ll ans = 0,cnt = 0;
int main()
{
ll n,x,y;cin>>n;
for(int i = 1;i<=n;i++)
{
cin>>x>>y;
x = x + maxn;//这边直接假设x输入的范围是0~~~2*1e5就行
sum[x] = y; //记录下每一个东西是多少
ans += x*y;
cnt +=y;
}
ll minn = ans;
ll kk = 0;
for(int i = 1;i<=2*maxn;i++)
{
ans+=kk;
ans-=cnt;
if(sum[i] > 0)
{
kk+=sum[i];
cnt-=sum[i];
}
minn = min(minn,ans);
}
cout<<minn<<endl;
return 0;
}
代码2:带权中位数
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5;
struct node
{
ll x,cnt;
node(){cnt = 0;}
}s[maxn+100];
bool cmp(node a,node b){
return a.x<b.x;
}
int main()
{
ll n;cin>>n;
ll sum = 0;
for(int i = 1;i<=n;i++)
{
cin>>s[i].x>>s[i].cnt;
sum+=s[i].cnt;
}
sort(s+1,s+1+n,cmp);//这个东西从小到大排列了
int flag;
if(sum%2==0) flag =1;
else flag = 0;
ll now = 0;
if(flag ==0)//表示是奇数的话
{
for(int i =1;i<=n;i++)
{
now = now + s[i].cnt;
if(now>=(sum/2+1))
{
ll ans = 0;
for(int j =1;j <= n;j++)
ans+=abs(s[j].x-s[i].x)*s[j].cnt;
cout<<ans<<endl;
return 0;
}
}
}else
{
for(int i =1;i<=n;i++)
{
now = now + s[i].cnt;
if(now >= sum/2+1)//表示两者皆大皆相同
{
ll ans = 0;
for(int j =1;j <= n;j++)
ans+=abs(s[j].x-s[i].x)*s[j].cnt;
cout<<ans<<endl;
return 0;
}else if(now == sum/2)
{
ll ans1 = 0;
for(int j =1;j <= n;j++)
ans1+=abs(s[j].x-s[i].x)*s[j].cnt;
ll ans2 = 0;
for(int j =1;j <= n;j++)
ans2+=abs(s[j].x-s[i+1].x)*s[j].cnt;
cout<<min(ans1,ans2)<<endl;
}
}
}
return 0;
}