距离之和最小 V3 51Nod - 1110(带权中位数或者爆搜)

51Nod - 1110

X轴上有N个点,每个点除了包括一个位置数据Xi,还包括一个权值Wi。点P到点Pi的带权距离 = 实际距离 * Pi

的权值。求X轴上一点使它到这N个点的带权距离之和最小,输出这个最小的带权距离之和。
Input 第1行:点的数量N。(2 <= N <= 10000)
第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 1
Sample 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;     	
} 




猜你喜欢

转载自blog.csdn.net/galesaur_wcy/article/details/80384930
今日推荐