【HDU 1864】【背包】最大报销额

  很经典的题目,做完之后感觉我被背包有了点新的感悟。其实就是在于浮点数拿去放大一百倍就可以用背包存了,然后就没什么难点了


#include "stdio.h"
#include "string.h"
int dp[3005000];//一开始直接用30050结果不行,因为后面是浮点数啊,当然要扩大100倍以后才可以用背包。
int receipt[100];
int max(int a,int b)
{
    return a>b?a:b;
}
int main(int argc, char const *argv[])
{
    double sum2;
    int    t,num,flag,n,sum;
    double a,b,c,d;
    char   ch;
    while(~scanf("%lf %d",&sum2,&t) && t)
    {
        memset(dp,0,sizeof(dp));
        memset(receipt,0,sizeof(receipt));
        sum=sum2*100;
        n=0;
        flag=1;
        for (int i = 0; i < t; ++i)
        {   
            a=b=c=0;
            flag=1;
            scanf("%d",&num);
            getchar();
            for (int j = 0; j < num; ++j)
            {
                scanf("%c:%lf",&ch,&d);
                getchar();
                if(ch=='A' || ch=='B' || ch=='C')
                {
                    if(ch=='A')
                        a+=d;
                    if(ch=='B')
                        b+=d;
                    if(ch=='C')
                        c+=d;
                   // printf("aaa=%lf %lf %lf\n",a,b,c);
                }
                else
                    flag=0;

                if(a>600 || b>600 || c>600)
                    flag=0;

                if((a+b+c)>1000)
                    flag=0;
            }
          //  printf("%d\n",flag);
            if(flag)
                receipt[n++]=(a+b+c)*100;
           // printf("%d\n",receipt[n-1]);
        }
       /* printf("1\n");
        for (int i = 0; i < n; ++i)
        {
            printf("sz=%d\n",receipt[i]);
        }*/
        for(int i = 0; i<n; i++)
        { 
            for(int j = sum; j>=receipt[i]; j--) 
            {
                    dp[j] = max(dp[j],dp[j-receipt[i]]+receipt[i]); 
            }
        } 
        //printf("%d\n",sum);
        printf("%.2lf\n",dp[sum]/100.0);  
    }
    return 0;
}


你可能感兴趣的:(c,背包,水题)