码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 1864 01背包

时间:2018-04-21 13:29:36      阅读:151      评论:0      收藏:0      [点我收藏+]

标签:ble   names   printf   允许   --   target   代码   php   AC   

题目链接: 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背包

标签:ble   names   printf   允许   --   target   代码   php   AC   

原文地址:https://www.cnblogs.com/yuluoluo/p/8900621.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!