题意:
一堆发票,找出:
1、只有 ABC 类型销售的
2、每一种销售类型(题意不清)A B C 不能超过600元
3、每张发票总金额不超过1000元
在金额m之下的最大金额
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <algorithm>
using namespace std;
const int NN=500000;
double m,a[NN];
double money1[NN],money2[NN];
struct node
{
int posi;
double value;
} stack[NN];
int num1,num2;
int n;
void dfs1(int s,int e)
{
memset(stack,0,sizeof(stack));
int top=1;
stack[0].posi=s;
for (int i=0;i<top;++i)
{
if (stack[i].posi>e)
{
money1[num1++]=stack[i].value;
continue;
}
stack[top].posi=stack[top+1].posi=stack[i].posi+1;
stack[top].value=stack[i].value;
stack[top+1].value=stack[i].value+a[stack[i].posi];
top+=2;
}
}
void dfs2(int s,int e)
{
memset(stack,0,sizeof(stack));
int top=1;
stack[0].posi=s;
for (int i=0;i<top;++i)
{
if (stack[i].posi>e)
{
money2[num2++]=stack[i].value;
continue;
}
stack[top].posi=stack[top+1].posi=stack[i].posi+1;
stack[top].value=stack[i].value;
stack[top+1].value=stack[i].value+a[stack[i].posi];
top+=2;
}
}
int main()
{
while (scanf("%lf%d",&m,&n),n>0)
{
int num=0;
memset(a,0,sizeof(a));
for (int i=0;i<n;++i)
{
bool canuse=true;
int k;double all=0.0;
char tmp[NN];
scanf("%d",&k);
double ma,mb,mc;
ma=mb=mc=0.00;
while (k--)
{
memset(tmp,0,sizeof(tmp));
scanf("%s",&tmp);
if (tmp[0]!='A' && tmp[0]!='B' && tmp[0]!='C') canuse=false;
double b;
char ccc;
sscanf(tmp+2,"%lf",&b);
if (b>600) canuse=false;
if (tmp[0]=='A') ma+=b;
else if (tmp[0]=='B') mb+=b;
else if (tmp[0]=='C') mc+=b;
}
all=ma+mb+mc;
if (ma>600) canuse=false;
if (mb>600) canuse=false;
if (mc>600) canuse=false;
if (all>min(1000.0,m)) canuse=false;
if (canuse) a[num++]=all;
}
memset(money1,0,sizeof(money1));
memset(money2,0,sizeof(money2));
num1=num2=0;
dfs1(0,num/2);
dfs2(num/2+1,num-1);
sort(money1,money1+num1);
sort(money2,money2+num2);
double ans=-1.0;
int p=0,q=num2-1;
for (;p<num1;++p)
{
while (money1[p]+money2[q]>m && q>=0) --q;
if (q>=0) ans=max(ans,money1[p]+money2[q]);
}
printf("%.2lf\n",ans);
}
}