[ABC274F] Fishing

Problem Statement

On a number line, there are N fish swimming.

Fish i, which has a weight of Wi, is at the coordinate Xi at time 0 and moves at a speed of Vi 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

  • 1N2000
  • 1A104
  • 1Wi104
  • 0Xi104
  • 1Vi104
  • 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);
}
posted @   灰鲭鲨  阅读(48)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示