Light OJ 1017 - Brush (III)
题目大意:
在一个二维平面上有N个点,散落在这个平面上。现在要清理这些点。有一个刷子刷子的宽度是w. 刷子上连着一根绳子,刷子可以水平的移动(在X轴方向上)。他可以把刷子放在任何一个地方然后开始移动(只能是水平的)。 他可以把在宽度为w的这个水平方向上的所有点都擦除掉。问最多移动k次,最多可以擦除多少个点?
题目解析:
根据题意,其实我们只需要考虑y坐标就OK了。 然后排序,把数据处理一下。
dp[i][k] = dp[第i个位置][移动的是第k次] = 最大数量
我们把数据预处理一下。 把每个位置以这个为起点,最大能包住多少个点。
我们把数据预处理一下。 把每个位置以这个为起点,最大能包住多少个点。
=======================================================================================
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> #include<queue> #include<vector> #include<map> using namespace std; typedef long long LL; #define Max(a,b) (a>b?a:b) const int INF = 1e9+7; const int maxn = 255; const int MOD = 9973; int a[maxn], dp[maxn][maxn];///dp[以第i个点为起点][粉刷了k次] = 最大数量 int main() { int n, w, K, T, cas = 1; scanf("%d", &T); while(T --) { memset(dp, 0, sizeof(dp)); scanf("%d %d %d", &n, &w, &K); for(int i=0; i<n; i++) scanf("%*d%d", &a[i]); sort(a, a+n); int ans = 0; for(int i=0; i<n; i++) { for(int j=i; j<n; j++) { if(a[j] - a[i] <= w) dp[i][1] ++; else break; } ans = max(ans, dp[i][1]); } for(int i=0; i<n; i++)///第i个位置 { for(int k=2; k<=i+1 && k<=K; k++)///第i个位置,总共选择k次 { for(int j=0; j < i; j++) { if(a[i] - a[j] > w) dp[i][k] = max(dp[i][k],dp[j][k-1] + dp[i][1]); else break; } ans = max(ans, dp[i][k]); } } printf("Case %d: %d\n",cas++, ans); } return 0; }