You can assume that the rope is sufficiently large. SinceSamir is too lazy, he doesn't want to clean all the room. Instead of doing ithe thought that he would use at most k moves. Now he wants to find themaximum number of dust units he can clean using at most k moves. Pleasehelp him.
Input
Input starts with an integer T (≤ 100),denoting the number of test cases.
Each case starts with a blank line. The next line containsthree integers N (1 ≤ N ≤ 100), w (1 ≤ w ≤ 10000)and k (1 ≤ k ≤ 100). N means that there are N dustpoints. Each of the next N lines contains two integers: xiyi denoting the coordinates of the dusts. You can assume that (-109≤ xi, yi ≤ 109) and all pointsare distinct.
Output
For each case print the case number and the maximum numberof dusts Samir can clean using at most k moves.
先预处理对于每一个y值,有多少可以清理掉的点
定义dp[i][j] := 前i个y值移动j步可以清理的最大垃圾量. 如果没有一次可以清理w行这个条件的话,类似01背包 dp[i][j] = max(dp[i-1[j], dp[i-1]j-1] + v); v(v是第i个y值对应的垃圾个数)
添上这个条件后,我们需要看上一次清理垃圾清理到了第几行.
假如说对y进化降序数据是
i x y
1 0 4
2 0 3
3 0 2
4 0 1
此时w = 2
当i = 4 时
dp[4][j] = max(dp[3][j], dp[1][j-1] + sigam(v));
当选择清理第4行垃圾时,他最多也可以清理掉i = 3,i = 2 行的垃圾。因为他们对应的 y2 - w <= y4.
于是他应该由y = 1 转移过来。
/***********************************************
* Author: fisty
* Created Time: 2015/6/25 22:42:29
* File Name : 1017.cpp
*********************************************** */
#include <iostream>
#include <cstring>
#include <deque>
#include <cmath>
#include <queue>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <string>
#include <vector>
#include <cstdio>
#include <bitset>
#include <algorithm>
using namespace std;
#define Debug(x) cout << #x << " " << x <<endl
#define Memset(x, a) memset(x, a, sizeof(x))
const int INF = 0x3f3f3f3f;
typedef long long LL;
typedef pair<int, int> P;
#define FOR(i, a, b) for(int i = a;i < b; i++)
#define MAX_N 110
int t;
int n, w, k;
struct node{
int y;
int num;
}p[MAX_N];
int dp[MAX_N][MAX_N];
bool cmp(node a, node b){
return a.y > b.y;
}
int main() {
//freopen("in.cpp", "r", stdin);
cin.tie(0);
ios::sync_with_stdio(false);
cin >> t;
int cnt = 1;
while(t--){
Memset(p, 0);
map<int, int> mp;
cin >> n >> w >> k;
FOR(i, 0, n){
int x, y;
cin >> x >> y;
if(mp.find(y) == mp.end()){
mp[y] = 1;
}else{
mp[y]++;
}
}
map<int, int>::iterator it;
int m = 0;
for(it = mp.begin(); it != mp.end(); it++){
p[++m].y = it->first;
p[m].num = it->second;
}
sort(p+1, p+1+m, cmp);
Memset(dp, 0);
for(int i = 1;i <= m; i++){
for(int j = 1;j <= k; j++){
int sum = 0;
for(int l = i;l >= 1; l--){
if(p[l].y - p[i].y > w) break;
sum += p[l].num;
dp[i][j] = max(dp[i-1][j], dp[l-1][j-1]+sum);
}
}
}
cout << "Case" << " " << cnt++ << ": ";
cout << dp[m][k] << endl;
}
return 0;
}