hdu 1864 01背包

Posted 三人行

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu 1864 01背包相关的知识,希望对你有一定的参考价值。

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1864

解题思路:首先这题一看就是01背包,那么要思考的就是用什么作为背包容量,这里报销价格是浮点数,所以我们最好选择发票张数来作为背包的容量。这样数组也非常小,因为最多才30张

     那么状态转移方程就是  dp[j] = max (dp[j],dp[j-1]+price);  那么很明显报销张数越多报销金额越大,发票张数从大到小循环,直到遇到满足条件的报销金额,那么它就是答案。
     这题有些坑,首先每张发票上,同类商品价值和不能超过600,还有除A、B、C 三类商品外,含有其他品种该发票也作废。我是先用gechar() 处理掉字符,再接受浮点数。

 

AC代码:

#include <stdio.h>
#include <string.h>
#include <algorithm>
#define MAX 33
using namespace std;

double dp[MAX];

int main ()
{

   int n;
   char ch1;
   double p = 0;//允许报销的最大金额
   double price = 0;
   double p_a = 0;//分别对应a.b.c三类物品的总价值
   double p_b = 0;
   double p_c = 0;

  while(scanf("%lf%d",&p,&n)== 2 && n)
  {
    int m = 0 ;
    memset (dp,0,sizeof(dp));
   for (int i=0;i<n;++i)
    {
      scanf("%d",&m);
      price = 0;
      int flag = 1;//标记该发票是否具有报销资格。1表示有
      p_a = p_b =p_c = 0;
     for (int j = 0;j<m;++j)
     {
        double t_p;
        int  p_ch = 0;
      while( ( ch1 = getchar() ) !=:)//对字符的处理
        {
          if(ch1 ==A) p_ch = 1;
          if (ch1 == B) p_ch = 2;
          if (ch1 == C) p_ch = 3;  
        }
 
      scanf ("%lf",&t_p);
      if (p_ch == 0) flag = 0;//作废的票
      if (p_ch == 1) p_a +=t_p;  
      if (p_ch == 2) p_b +=t_p;  
      if (p_ch == 3) p_c +=t_p;
       
      if (p_a > 600 || p_b > 600 || p_c >600) flag = 0;
      price += t_p; //记录整张发票的总额
     }
        if (price > 1000   || !flag) continue;
       for (int j = n;j>= 1;--j)
        dp[j] = max (dp[j],dp[j-1]+price);
  }
   double ans = 0;
   for (int i =n;i>=0;--i)
    if (dp[i] <= p) {ans = dp[i];break;}

    printf ("%.2lf\n",ans);
   }
return 0 ;
}

 

以上是关于hdu 1864 01背包的主要内容,如果未能解决你的问题,请参考以下文章

HDU 1864 01背包

HDU1864_最大报销额(背包/01背包)

HDU-1864&&HDU-2602(01背包问题)

HDU1864 最大报销额 01背包

hdu 1864 最大报销额01背包

hdu1864 最大报销额(01背包)