http://acm.hdu.edu.cn/showproblem.php?pid=1864
dp算法:
#include<stdio.h>
#include<memory.h>
int m,n,dp[3000001]; //dp[i]表示i元钱所能报销的的最大额度
int price[32];
int k; //k表示有报销资格的发票数
void search()
{
int i,j,t;
memset(dp,0,sizeof(dp));
for(i=0;i<k;i++)
{
t=price[i];
for(j=m;j>=t;j--)
{
if(dp[j]<dp[j-t]+t)
dp[j]=dp[j-t]+t;
}
}
}
int main()
{
int i,j,f;
int a,b,c;
char ch;
double fl,q;
bool tag;
freopen("in.txt","r",stdin);
while(scanf("%lf%d",&q,&n)!=EOF)
{
if(n==0) break;
m=(int)(q*100);
k=0;
memset(price,0,sizeof(price));
for(i=0;i<n;i++)
{
scanf("%d",&f);
a=0,b=0,c=0;
tag=true;
for(j=0;j<f;j++)
{
scanf(" %c:%lf",&ch,&fl);
if(ch=='A')
a+=(int)(fl*100);
else if(ch=='B')
b+=(int)(fl*100);
else if(ch=='C')
c+=(int)(fl*100);
else
tag=false;
}
if(a>60000 || b>60000 || c>60000 || a+b+c>100000)
tag=false;
if(tag)
price[k++]=a+b+c;
}
search();
printf("%.2lf/n",(double)dp[m]/100.0);
}
fclose(stdin);
return 0;
}
搜索算法:
#include<stdio.h>
int n,k;
double q;
double price[32];
double max;
void fun(int left,double qq) //qq表示余额
{
if(q-qq>max)
max=q-qq;
if(max==q) return;
if(left<k)
{
if(qq>=price[left])
fun(left+1,qq-price[left]);
fun(left+1,qq);
}
}
int main()
{
int i,m;
char ch;
double f;
double a,b,c;
bool tag;
while(scanf("%lf%d",&q,&n))
{
if(n==0) break;
k=0;
max=0;
for(i=0;i<n;i++)
{
scanf("%d",&m);
a=0,b=0,c=0;
tag=true;
while(m--)
{
scanf(" %c:%lf",&ch,&f);
if(ch=='A')
a+=f;
else if(ch=='B')
b+=f;
else if(ch=='C')
c+=f;
else
tag=false;
}
if(a>600 || b>600 || c>600 || a+b+c>1000)
tag=false;
if(tag)
price[k++]=a+b+c;
}
fun(0,q);
printf("%.2lf/n",max);
}
return 0;
}