一开始没有看懂题.
后来看懂题了,发现这是一道水题。
首先,把两两点之间的值求出来,排一个序,然后在这个序列上二分。
二分出一个值x,表示DP时候的两两点的值不能超过这个x。
设f[i]表示最后一个走到i的最大积分。
那么如果g[i][j]<=x&&f[i]>f[j]+1那么f[i]就可以转移。
但是很容易被卡常,本来我的DP是打max的,然后改成直接判断就A了。
#include
#include
#include
#include
#include
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fod(i,a,b) for(i=a;i>=b;i--)
using namespace std;
const int maxn=2007;
int i,j,k,l,n,m,r,mid;
int f[maxn];
int x[maxn],y[maxn],t[maxn];
int ans1,ans2,ans3,num;
double o,ans,pan,g[maxn][maxn];
struct node{
double z;
int a;
}a[maxn*maxn];
double ju(int x,int y,int xx,int yy){
return (xx-x)*(xx-x)+(yy-y)*(yy-y);
}
int gcd(int x,int y){
return(!y)? x:gcd(y,x%y);
}
bool cmp(node x,node y){
return x.zint main(){
scanf("%d%d",&n,&m);
fo(i,1,n){
scanf("%d%d%d",&t[i],&x[i],&y[i]);
}
fo(i,1,n){
fo(j,0,i-1){
if(i==j)continue;
g[i][j]=a[++num].z=sqrt(ju(x[i],y[i],x[j],y[j]))/(t[i]-t[j]);
a[num].a=i*n+j;
}
}
sort(a+1,a+1+num,cmp);
l=1,r=num;
while(l2;pan=a[mid].z;
memset(f,128,sizeof(f));f[0]=0;
fo(i,1,n){
fo(j,0,i-1){
if(g[i][j]<=pan&&f[i]1)f[i]=f[j]+1;
}
}
fo(i,1,n)if(f[i]>=m)break;
if(f[i]>=m)r=mid;else l=mid+1;
}
i=a[l].a/n,j=a[l].a%n;
ans1=ju(x[i],y[i],x[j],y[j]),ans3=abs(t[i]-t[j]);
fod(i,sqrt(ans1),1){
if(ans1%(i*i)==0){
ans2=ans1/(i*i);ans1=i;
break;
}
}
l=gcd(ans1,ans3);
ans1/=l,ans3/=l;
printf("%d %d %d\n",ans1,ans2,ans3);
}