简单分组背包,同一斜率为一组。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
double EP=1e-8;
int n, T, vis[205], sum[205], cnt, dp[40005];
struct node{
int x, y, t, v;
}p[205];
struct line{
node pt[205];
}pp[205];
bool cmp(node p1, node p2){
return p1.y<p2.y;
}
int getmax(int x, int y){
return x>y?x:y;
}
int main(){
//freopen("1.txt", "r", stdin);
int t, ans, i, j, cas=1;
while(scanf("%d%d", &n, &T)!=EOF){
cnt=0;ans=0;
memset(sum, 0, sizeof(sum));
memset(vis, 0, sizeof(vis));
memset(dp, 0, sizeof(dp));
for(i=0; i<n; i++){
scanf("%d%d%d%d", &p[i].x, &p[i].y, &p[i].t, &p[i].v);
}
for(i=0; i<n; i++){
if(vis[i])continue;
vis[i]=1;
double k=1.0*p[i].x/p[i].y;
pp[cnt].pt[sum[cnt]++]=p[i];
for(j=i+1; j<n; j++){
if(!vis[j]&&fabs(1.0*p[j].x/p[j].y-k)<EP){
vis[j]=1;
pp[cnt].pt[sum[cnt]++]=p[j];
}
}
cnt++;
}
for(i=0; i<cnt; i++){
if(sum[i]<2)continue;
sort(pp[i].pt, pp[i].pt+sum[i], cmp);
for(j=1; j<sum[i]; j++){
pp[i].pt[j].t+=pp[i].pt[j-1].t;
pp[i].pt[j].v+=pp[i].pt[j-1].v;
}
}
for(i=0; i<cnt; i++){
for(j=T; j>=0; j--){
for(t=0; t<sum[i]; t++){
if(j-pp[i].pt[t].t>=0)
dp[j]=getmax(dp[j], dp[j-pp[i].pt[t].t]+pp[i].pt[t].v);
if(dp[j]>ans)ans=dp[j];
}
}
}
printf("Case %d: %d\n", cas++,ans);
}
return 0;
}