而为坐标平面上给出n个点,问一把款w的刷子,横着刷k次最多能够刷掉多少个点。
因为是横着刷,所以只考虑纵坐标。
dp[i][k]表示前i个点刷k次最多能够刷的点数。。。然后就是枚举,不过要先处理完所有dp[i][1]的情况。。。
开始想的是dp[i][j][k]表示区间[i,j]刷k次能够刷的最多点,,,但是转移出问题了。。。感觉无法转移状态。。。
/***************************************** Author :Crazy_AC(JamesQi) Time :2015 File Name : *****************************************/ // #pragma comment(linker, "/STACK:1024000000,1024000000") #include <iostream> #include <algorithm> #include <iomanip> #include <sstream> #include <string> #include <stack> #include <queue> #include <deque> #include <vector> #include <map> #include <set> #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <climits> using namespace std; #define MEM(x,y) memset(x, y,sizeof x) #define pk push_back typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> ii; const double eps = 1e-10; const int inf = 1 << 30; const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; const int maxn = 110; int dp[maxn][maxn]; int A[maxn]; int n,Times,w; int main() { // freopen("in.txt","r",stdin); // freopen("out1.txt","w",stdout); int t,icase = 0; scanf("%d",&t); while(t--){ scanf("%d%d%d",&n,&w,&Times); for (int i = 1;i <= n;++i) scanf("%*d%d",&A[i]); sort(A + 1,A +1 + n); memset(dp, 0,sizeof dp); int ans = 0; for (int j = n;j >= 1;--j){ for (int i = j;i >= 1;--i){ dp[j][1] += (A[j] - A[i] <= w); } ans = max(dp[j][1], ans); } for (int j = 1;j <= n;++j){ for (int k = 2;k <= Times;++k){ for (int i = 1;i < j;++i){ if (A[j] - A[i] > w) dp[j][k] = max(dp[j][k], dp[j][1] + dp[i][k-1]); } ans = max(ans, dp[j][k]); } } cout << "Case " << ++icase << ": " ; cout << ans << endl; } return 0; }