hdu 4341 Gold miner 分组背包

来源:互联网 发布:linux libgcc s.so 编辑:程序博客网 时间:2024/05/01 02:13

简单分组背包,同一斜率为一组。

 

#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;}