分组背包,先排序处理共线的,对边同一组的要先选前面的才能选后面的,所以后面的加上前面的时间和价值
在做分组背包处理
代码:
#include <stdio.h> #include <stdlib.h> #include <math.h> #include <string.h> #include <iostream> #include <algorithm> using namespace std; int total,gold; int dp[40005]; int k,sign=1; struct node { int a; int b; int time; int value; }ak[205],num[205][205],ks; int cmp(const void *a,const void *b) { struct node *a1=(struct node *)a; struct node *b1=(struct node *)b; if((a1->b)*(b1->a)==(a1->a)*(b1->b)) return ((a1->a)*(a1->a)+(a1->b)*(a1->b))-((b1->a)*(b1->a)+(b1->b)*(b1->b)); else return (a1->b)*(b1->a)-(a1->a)*(b1->b); } int main() { while(scanf("%d%d",&gold,&total)!=EOF) { memset(dp,0,sizeof(dp)); int i,j,m; int maxn=0; memset(ak,0,sizeof(ak)); memset(num,0,sizeof(num)); for(i=1;i<=gold;i++) { scanf("%d%d%d%d",&ak[i].a,&ak[i].b,&ak[i].time,&ak[i].value); } qsort(ak+1,gold,sizeof(ak[0]),cmp); ks.time=ak[1].time,ks.value=ak[1].value; num[1][0].time=ks.time,num[1][0].value=ks.value; int knum=1; int len=0; for(i=2;i<=gold;i++) { if(ak[i].a*ak[i-1].b==ak[i].b*ak[i-1].a) { len++; ks.time+=ak[i].time,ks.value+=ak[i].value; num[knum][len].time=ks.time,num[knum][len].value=ks.value; } else { knum++; len=0; ks.time=ak[i].time,ks.value=ak[i].value; num[knum][len].time=ks.time,num[knum][len].value=ks.value; } } for(i=1;i<=knum;i++) { for(j=total;j>=0;j--) { for(k=0;num[i][k].time>0;k++) { if(j>=num[i][k].time) { dp[j]=max(dp[j],dp[j-num[i][k].time]+num[i][k].value); } } } } printf("Case %d: %d\n",sign++,dp[total]); } }