dp[i][j]代表前i个刷子 刷前j个点 再枚举当前刷子以某个点为起点能获得的最大值
#include <bits/stdc++.h>
using namespace std;
struct node
{
int x;
int y;
};
node point[110];
int dp[110][110];
int pos[110],sum[110];
int n,w,m;
int main()
{
int t,cas,i,j,k,p,val,x,y,maxx1,maxx2;
scanf("%d",&t);
for(cas=1;cas<=t;cas++)
{
scanf("%d%d%d",&n,&w,&m);
for(i=1;i<=n;i++)
{
scanf("%d%d",&point[i].x,&point[i].y);
}
for(i=1;i<=n;i++)
{
pos[i]=point[i].y;
}
sort(pos+1,pos+n+1);
for(i=1,j=0;i<=n;i++)
{
if(j==0||pos[j]!=pos[i])
{
pos[++j]=pos[i];
sum[j]=1;
}
else sum[j]++;
}
n=j;
for(i=1;i<=n;i++)
{
sum[i]+=sum[i-1];
}
memset(dp,0,sizeof(dp));
for(i=1;i<=m;i++)
{
for(j=1;j<=n;j++)
{
dp[i][j]=dp[i-1][j];
for(k=1;k<=j;k++)
{
p=lower_bound(pos+1,pos+n+1,pos[k]-w)-pos-1;
dp[i][j]=max(dp[i][j],dp[i-1][p]+sum[k]-sum[p]);
}
}
}
printf("Case %d: %d\n",cas,dp[m][n]);
}
return 0;
}