题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1864
大意:对于每张发票,要么报销,要么不报销,0-1背包,张数即为背包;转移方程:f[j]=max(f[j],f[j-1]+v[i]);
一开始边界没考虑,导致输出结果为0.00;

1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 using namespace std; 5 double price[1000]; 6 double dp[1000]; 7 8 int main(){ 9 double Q; 10 int N,m,n; 11 char ch; 12 while(scanf("%lf%d",&Q,&N)!=EOF){ 13 if(N==0)break; 14 memset(dp,0,sizeof(dp)); 15 memset(price,0,sizeof(price)); 16 n=0; 17 for(int i=0;i<N;i++){ 18 scanf("%d",&m); 19 double sum=0,p1=0,p2=0,p3=0,p; 20 int flag=0; 21 while(m--){ 22 scanf(" %c:%lf",&ch,&p); 23 if(ch=='A')p1+=p; 24 else if(ch=='B')p2+=p; 25 else if(ch=='C')p3+=p; 26 else { 27 flag=1; 28 break; 29 } 30 sum+=p; 31 } 32 if(sum>1000||p1>600||p2>600||p3>600||flag)continue; 33 else price[n++]=sum; 34 } 35 sort(price,price+n); 36 memset(dp,0,sizeof(dp)); 37 for(int i=0;i<=n;i++){ 38 for(int j=n;j>=1;j--){ 39 if(dp[j-1]+price[i]<=Q){ 40 dp[j]=max(dp[j],dp[j-1]+price[i]); 41 } 42 } 43 } 44 int k=0; 45 for(int i=1;i<=n;i++){ 46 if(dp[k]<dp[i])k=i; 47 } 48 printf("%.2lf\n",dp[k]); 49 } 50 return 0; 51 }