测评会员优惠活动进行中 · 开通 VIP,有效期内测评不限次 VIP 优惠中 · 测评不限次 立即查看

A40859. 密文搜索

填空题 困难

题目描述

密文搜索

题目描述

蓝桥村的居民都生活在一条公路的边上,公路的长度为L,每户家庭的 位置都用这户家庭到公路的起点的距离来计算,第i户家庭距起点的距 的终点。

已知每户家庭都会向着远离公路起点的方向去参加集会,参加集会的路程开销为家庭内的人数ti与距离的乘积。

给定每户家庭的位置di和人数ti,请为村委会寻找最好的集会举办地:p1, p2, p3, p4 (p1<=p2<=p3<=p4=L),使得村内所有人的路程开销和最小。

输入格式

输入的第一行包含两个整数n, L,分别表示蓝桥村的家庭数和公路长度。

接下来n行,每行两个整数di, ti,分别表示第i户家庭距离公路起点的距离和家庭中的人数。

输出格式

输出一行,包含一个整数,表示村内所有人路程的开销和。

样例输入

6 10

1 3

2 2

4 5

5 20

6 5

8 7

样例输出

18

参考答案

#include<stdio.h> #include<iostream> #include<string.h> #include<vector> #include<math.h> #include<algorithm> #include<set> #include<string.h> #include<string> #include<map> #include<queue> using namespace std; #define N 100008 #define ll long long #define ull unsigned long long #define inf 0x3f3f3f3f struct node{ ll dis,num; }p[N]; ll num[N],d[N];//d[i]表示p[i]到p[i-1]的距离 ll s4[N]; int main(){ int n; ll L; scanf("%d%I64d",&n,&L); int x,y; num[0]=0ll; for(int i=1;i<=n;i++){ num[i]=0ll; scanf("%I64d%I64d",&p[i].dis,&p[i].num); num[i]=num[i-1]+p[i].num; if(i==1)d[i]=0; else d[i]=p[i].dis-p[i-1].dis; } p[n+1].dis=L;p[n+1].num=0; if(n<=3){ printf("0\n"); } else{ s4[n+1]=0; for(int i=n;i>=1;i--){//从i点到n+1点所有人需要走到s4的距离 s4[i]=s4[i+1]+ (p[n+1].dis-p[i].dis)*p[i].num; } ll ans=(ll)inf*1000; ll s1=0,s2=0,s3=0; for(int i=1;i<=n-2;i++){//暴力枚举三个点的位置 s1+= num[i-1]*d[i]; s2=0; if(s1>=ans)continue; for(int j=i+1;j<=n-1;j++){ s2+= ( num[j-1]-num[i])*d[j]; s3=0; if(s1+s2>=ans)continue; for(int k=j+1;k<=n;k++){ s3+=(num[k-1]-num[j])*d[k]; ll s=s4[k+1];//表示最后一段的结果 if(ans>s1+s2+s3+s){ // printf("%d %d %d %d\n",i,j,k,n+1);输出新区间 ans=s1+s2+s3+s; } } } } printf("%I64d\n",ans); } return 0; }
上一题 下一题