hdu 1864 最大报销额 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1864
DFS
题目分析:求有上限的数列最大和,用DFS来做就可以。对题目的理解应该大致有这么几点,发票整张报销,所以有一条不合格,整张就废了;1000是每张发票的总额上限,600是每一项(种类ABC)的上限,还有个总上限,是要输入的。根据三个限制求出可报销发票的报销额,存在一个数组里,排序后DFS即可。
code:
#include<stdio.h>
#include<stdlib.h>
double max,ans,g[35];
int i,n;
int cmp(const void *a, const void *b)
{
return *( ( int * ) a ) - *( ( int * ) b );
}
void dfs(double sum,int k)
{
if(ans==max)return;
if(sum<=max&&sum>ans)ans=sum;
for(int i=k;i<n;i++)
{
if(sum+g[i]<=max)dfs(sum+g[i],i+1);
else break;
}
}
int main()
{
int m;
double a,b,c,sum,x;
char s;
while(scanf("%lf %d",&max,&n),n)
{
for(i=0;i<n;i++)
{
a=b=c=0;
scanf("%d",&m);
while(m--)
{
scanf(" %c:%lf",&s,&x);
switch(s)
{
case'A':a+=x;break;
case'B':b+=x;break;
case'C':c+=x;break;
default:a+=1001;
}
}
if(a+b+c<=1000&&a<=600&&b<=600&&c<=600)g[i]=a+b+c;
else i--,n--;
}
qsort(g,n,sizeof(double),cmp);
for(i=0;i<n;i++)
{
//printf("$$$g[%d]==%f\n",i,g[i]);
}
ans=-1;
dfs(0,0);
printf("%.2f\n",ans);
}
return 0;
}
PS:wrong了将近一小时,sad……复习一个知识点,在递归内部定义的变量,放在外部就错了。