[ABC274F] Fishing
Problem Statement
On a number line, there are $N$ fish swimming.
Fish $i$, which has a weight of $W_i$, is at the coordinate $X_i$ at time $0$ and moves at a speed of $V_i$ in the positive direction.
Takahashi will choose an arbitrary real number $t$ greater than or equal to $0$ and do the following action at time $t$ just once.
Action: Choose an arbitrary real number $x$. Catch all fish whose coordinates are between $x$ and $x+A$, inclusive.
Find the maximum total weight of fish that he can catch.
Constraints
- $1 \leq N \leq 2000$
- $1 \leq A \leq 10^4$
- $1 \leq W_i\leq 10^4$
- $0 \leq X_i\leq 10^4$
- $1 \leq V_i\leq 10^4$
- All values in the input are integers.
Input
The input is given from Standard Input in the following format:
$N$ $A$ $W_1$ $X_1$ $V_1$ $W_2$ $X_2$ $V_2$ $\vdots$ $W_N$ $X_N$ $V_N$
Output
Print the answer.
Sample Input 1
3 10 100 0 100 1 10 30 10 20 10
Sample Output 1
111
At time $0.25$, fish $1$, $2$, and $3$ are at the coordinates $25$, $17.5$, and $22.5$, respectively. Thus, the action done at this time with $x=16$ catches all the fish.
Sample Input 2
3 10 100 100 100 1 10 30 10 20 10
Sample Output 2
100
One optimal choice is to do the action at time $0$ with $x=100$.
Sample Input 3
4 10 1000 100 10 100 99 1 10 0 100 1 1 1
枚举我们选择的第一条鱼。那么如果现在的时间是 \(t\),如果 \(t\) 秒时一条鱼在这条鱼的右边 \(a\) 格以内,那么这条鱼就能被选中。
称这条鱼的右边 \(a\) 格为答案区间,我们可以算出剩下每条鱼进入答案区间的时间和出来的时间,从而算出每条鱼被算入答案的时间区间。其实就是根据速度大小和差了多远去判断。当然,如果一直不在,就不理这条鱼。如果一直都在,就把这个区间设为 \([1,10000]\)。然后现在要选定一个时间,让他被覆盖的次数最多。那么把所有时间离散化,差分就可以了。
#include<bits/stdc++.h>
using namespace std;
const int N=2005;
int n,x[N],w[N],v[N],c[N<<1],m,ans;
double lsh[N<<1];
struct node{
double l,r;
int w;
}xd[N];
int abss(int x)
{
return x<0? -x:x;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d%d%d",w+i,x+i,v+i);
for(int i=1;i<=n;i++)
{
int k=0,idx=0;
memset(c,0,sizeof(c));
for(int j=1;j<=n;j++)
{
if(v[i]==v[j])
{
if(x[j]>=x[i]&&x[j]-x[i]<=m)
{
xd[++k].l=0,xd[k].r=100000;
lsh[++idx]=0,lsh[++idx]=100000;
xd[k].w=w[j];
}
}
if(v[i]<v[j]){
if(x[j]-x[i]>m)
continue;
if(x[j]>=x[i])
xd[++k].l=0;
else
xd[++k].l=1.00*(x[i]-x[j])/(v[j]-v[i]);
xd[k].r=1.00*(x[i]+m-x[j])/(v[j]-v[i]);
xd[k].w=w[j];
lsh[++idx]=xd[k].l;
lsh[++idx]=xd[k].r;
}
if(v[i]>v[j])
{
if(x[j]<x[i])
continue;
if(x[i]+m>x[j])
xd[++k].l=0;
else
xd[++k].l=1.00*(x[j]-x[i]-m)/(v[i]-v[j]);
xd[k].r=1.00*(x[j]-x[i])/(v[i]-v[j]);
xd[k].w=w[j];
lsh[++idx]=xd[k].l;
lsh[++idx]=xd[k].r;
}
}
// printf("%d\n",k);
sort(lsh+1,lsh+idx+1);
for(int j=1;j<=k;j++)
{
int l=lower_bound(lsh+1,lsh+idx+1,xd[j].l)-lsh;
int r=lower_bound(lsh+1,lsh+idx+1,xd[j].r)-lsh;
c[l]+=xd[j].w,c[r+1]-=xd[j].w;
// printf("%d %d\n",l,r);
}
// putchar('\n');
for(int j=1;j<=idx;j++)
c[j]+=c[j-1],ans=max(ans,c[j]);
}
printf("%d",ans);
}