分组背包而已。注意的是,每个时间T,要把一组的全加进去比较一次。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <vector> #define N 205 #define T 41000 using namespace std; int dp[T]; struct node{ int x,y; int t,v; }Node[N]; struct zu{ int t,v; zu(int tt,int vv){ t=tt; v=vv; } }; vector<zu>pts[N]; bool cmp(node a,node b){ if(a.x*b.y-a.y*b.x>0) return true; else if(a.x*b.y-a.y*b.x==0){ if(a.x*a.x+a.y*a.y<b.x*b.x+b.y*b.y) return true; } return false; } int main(){ int n,t,kase=0; while(scanf("%d%d",&n,&t)!=EOF){ for(int i=0;i<n;i++){ scanf("%d%d%d%d",&Node[i].x,&Node[i].y,&Node[i].t,&Node[i].v); pts[i].clear(); } pts[n].clear(); sort(Node,Node+n,cmp); int al=1; pts[al].push_back(zu(Node[0].t,Node[0].v)); for(int i=1;i<n;i++){ if(Node[i].x*Node[i-1].y-Node[i].y*Node[i-1].x!=0) al++; pts[al].push_back(zu(Node[i].t,Node[i].v)); } for(int i=1;i<=al;i++){ int size=pts[i].size(); for(int k=1;k<size;k++){ pts[i][k].t+=pts[i][k-1].t; pts[i][k].v+=pts[i][k-1].v; } } memset(dp,0,sizeof(dp)); for(int i=1;i<=al;i++){ int size=pts[i].size(); for(int p=t;p>=0;p--) for(int k=0;k<size;k++){ if(p-pts[i][k].t<0) break; dp[p]=max(dp[p],dp[p-pts[i][k].t]+pts[i][k].v); } } printf("Case %d: %d\n",++kase,dp[t]); } return 0; }
时间: 2024-11-08 17:24:36