0-1背包问题
对于每一张发票,要么报销,要么不报销,张数就是dp值。
状态转移代码:
dp[j]=max(dp[j],dp[j-v[i]]+v[i])
注意测试数据的边界值和特殊值!
AC代码:
#include <stdio.h>
#include <string.h>
int dp[3000010];
int max(int a,int b)
{
return a>b?a:b;
}
int main()
{
int v[100];
double q,price,sum;
int n,m,i,j,A,B,C,Q;
char type,ms;
while(scanf("%lf %d",&q,&n), n!=0 )
{
int cnt=0;
Q=q*100;
for(i=0;i<n;i++)
{
int flag=0;
A=B=C=0;
scanf("%d",&m);
while(m--)
{
getchar();
scanf(" %c%c%lf",&type,&ms,&price);
if(type=='A')
A+=price*100;
else if(type=='B')
B+=price*100;
else if(type=='C')
C+=price*100;
else flag=1;
sum=A+B+C;
}
if( flag || A>60000 || B>60000 || C>60000 || sum>100000 || sum>Q )
flag=1;
if(!flag)
{
v[cnt++]=sum;
}
}
memset(dp,0,sizeof(dp));
for(i=0;i<cnt;i++)
for(j=Q;j>=v[i];j--)
{
dp[j]=max(dp[j],dp[j-v[i]]+v[i]);
}
printf("%.2f\n",dp[Q]*1.00/100.00);
}
return 0;
}