就题目来说还是属于比较常规的分组DP,处理点与点之间的关系稍微麻烦点,借鉴了网上结构体重载的方法
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
#define max(a, b) ((a) > (b) ? (a) : (b))
const int MAXN = 205;
int dp[40005];
struct Point {
int x, y;
int t, w;
void input() {
scanf("%d %d %d %d", &x, &y, &t, &w);
}
int operator * (const Point &p) const {
return x * p.y - y * p.x;
}
friend int dis(const Point &x) {
return x.x * x.x + x.y * x.y;
}
friend bool operator < (const Point &a, const Point &b) {
int temp = a * b;
if (temp == 0)
return dis(a) < dis(b);
return temp < 0;
}
} p[MAXN];
int main()
{
int n, time;
int c = 0;
while (scanf("%d %d", &n, &time) != EOF)
{
for (int i = 0; i < n; ++i)
p[i].input();
sort(p, p + n);
memset(dp, 0, sizeof(dp));
//dp[0] = 0;
for (int i = 0; i < n; ++i)
{
int j = i;
while (j + 1 < n && p[j+1] * p[i] == 0)
++j;
int tt, ww;
for (int t = time; t > 0; --t)
{
tt = 0; ww = 0;
for (int k = i; k <= j; ++k)
{
tt += p[k].t;
ww += p[k].w;
if (t >= tt)
dp[t] = max(dp[t], dp[t-tt] + ww);
}
}
i = j;
}
++c;
printf("Case %d: %d\n", c, dp[time]);
}
return 0;
}