Brush (III)
题目位置:
题意:
有n个点,坐标为xi 与 yi
就是说每一次你有一把刷子,可以刷 长度为 w 的一行扫过去,如图:
扫到的点就算结果,但是一个点只有0 1 状态!
求给你k次次刷的机会,问你最多刷到多少个点?
方法:
记录在j号点向下刷一下可以有多少的点被扫到,记录一个val[ ]数组里面!
然后就可以开始DP了!
方程如下:
if(i==1&&j!=0) dp[i][j]=1;
else if(!j) dp[i][j]=0;
else
dp[i][j]=std::max(dp[std::max(0,i-val[i])][j-1]+val[i],dp[i-1][j]);
代码:
#include <bits/stdc++.h>
#define F(i,a,b) for(int i=a;i<=b;i++)
#define F'(i,a,b) for(int i=a;i>=b;i--)
#define INF 0x3f3f3f3f
#define N 205
#define W(a) while(a--)
int T,n,w,k,x;
int dp[N][N],y[N],val[N];
int main()
{
scanf("%d",&T);
for(int loc=1;loc<=T;loc++)
{
scanf("%d%d%d",&n,&w,&k);
for(int i=1;i<=n;i++)
scanf("%d%d",&x,&y[i]);
memset(dp,0,sizeof(dp));
memset(val,0,sizeof(val));
std::sort(y+1,y+1+n);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(y[i]-w<=y[j]&&y[j]<=y[i]) val[i]++;
for(int i=1;i<=n;i++)
for(int j=0;j<=k;j++)
{
if(i==1&&j!=0) dp[i][j]=1;
else if(!j) dp[i][j]=0;
else
dp[i][j]=std::max(dp[std::max(0,i-val[i])][j-1]+val[i],dp[i-1][j]);
}
printf("Case %d: %d\n",loc,dp[n][k]);
}
return 0;
}