分组背包,先排序处理共线的,对边同一组的要先选前面的才能选后面的,所以后面的加上前面的时间和价值
在做分组背包处理
代码:
#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]);
}
}