题意:
给几个点,和一个一定宽度的刷子,在一定次数中,刷过最多的点的个数 。刷子可以水平无线延长刷。
题解:
dp[i][k] 第i个点,第k次刷,
初始化: dp[ i ] [1] 第一次 刷 i 点,会~接下来~影响几个点。
转移: dp[ i ][ k ] =max( dp[ i ] [ k ] ,dp[ i ][ 1 ] + dp[ j ][ k-1 ]);
#include <iostream>
#include <cstdio>
#include <math.h>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=105;
int a[maxn];
int dp[maxn][maxn];//dp[i][k] 第i个点 擦k次
int main()
{
int T;int t;int cas=0;
scanf("%d",&T);
while(T--){
int n,w,tim;
scanf("%d%d%d",&n,&w,&tim);
for(int i=1;i<=n;i++){
scanf("%d%d",&t,&a[i]);
}
sort(a+1,a+n+1);
int ans=0;
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++){//以i为底
for(int j=i;j<=n;j++){
if(a[j]-a[i]<=w)
dp[i][1]++;
}
ans=max(ans,dp[i][1]);
}
for(int i=1;i<=n;i++){// 去掉i
for(int k=2;k<=tim;k++){//擦k次
for(int j=1;j<i;j++){
if(a[i]-a[j]>w)
dp[i][k]=max(dp[i][k],dp[i][1]+dp[j][k-1]);
else break;
}
ans=max(ans,dp[i][k]);
}
}
printf("Case %d: %d\n",++cas,ans);
}
return 0;
}