zoukankan      html  css  js  c++  java
  • 九度OJ 1025 最大报销额(01背包)

    题目1025:最大报销额

    时间限制:1 秒

    内存限制:32 兆

    特殊判题:

    提交:2683

    解决:608

    题目描述:
    现有一笔经费可以报销一定额度的发票。允许报销的发票类型包括买图书(A类)、文具(B类)、差旅(C类),要求每张发票的总额不得超过1000元,每张发票上,单项物品的价值不得超过600元。现请你编写程序,在给出的一堆发票中找出可以报销的、不超过给定额度的最大报销额。
    输入:
    测试输入包含若干测试用例。每个测试用例的第1行包含两个正数 Q 和 N,其中 Q 是给定的报销额度,N(N<=30)是发票张数。随后是 N 行输入,每行的格式为:
    m Type_1:price_1 Type_2:price_2 ... Type_m:price_m
    其中正整数 m 是这张发票上所开物品的件数,Type_i 和 price_i 是第 i 项物品的种类和价值。物品种类用一个大写英文字母表示。当N为0时,全部输入结束,相应的结果不要输出。
    输出:
    对每个测试用例输出1行,即可以报销的最大数额,精确到小数点后2位。
    样例输入:
    200.00 3
    2 A:23.50 B:100.00
    1 C:650.00
    3 A:59.99 A:120.00 X:10.00
    1200.00 2
    2 B:600.00 A:400.00
    1 C:200.50
    1200.50 3
    2 B:600.00 A:400.00
    1 C:200.50
    1 A:100.00
    100.00 0
    样例输出:
    123.50
    1000.00
    1200.50
    来源:
    2007年浙江大学计算机及软件工程研究生机试真题

    MYCode
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using  namespace std;
    #define MAX  100010
    bool dp[MAX];
    int st[MAX];
    int main()
    {
         int n;
         double q;
         while(scanf( "%lf%d", &q, &n) != EOF)
        {
             if(n ==  0)
                 break;
            memset(dp,  0sizeof(dp));
             int i, j;
             int m;
             int ct =  0;
             for(i =  1; i <= n; i++)
            {
                scanf( "%d", &m);
                 char ch;
                 double val;
                 bool flag =  true;
                 double sum =  0;
                 char tp;
                 for(j =  1; j <= m; j++)
                {
                     //scanf("%c:%lf",&ch,&val);
                    cin >> ch >> tp >> val;
                    sum += val;
                     if(!(ch ==  'A' || ch ==  'B' || ch ==  'C'))
                        flag =  false;
                     if(sum >  1000)
                        flag =  false;
                     if(val >  600)
                        flag =  false;
                }
                 if(flag)
                {
                     //cout<<"ok "<<sum<<endl;
                    st[++ct] = ( int)(sum *  100);
                }
            }
             int cap = ( int)(q *  100);
            dp[ 0] =  true//note
             /*for(i=1;i<=ct;i++)
            cout<<st[i]<<" ";
            cout<<endl;*/

             int ans =  0;
             for(i =  1; i <= ct; i++)
            {
                 for(j = cap; j >= st[i]; j--)
                     //for(j=st[i];j<=cap;j++)
                {
                     if(dp[j - st[i]])
                    {
                        dp[j] =  true;
                         if(j > ans)
                            ans = j;
                    }
                }
            }
             /*for(i=cap;i>=0;i--)
            {
                if(dp[i])
                {
                    ans=i;
                    break;
                }
            }*/

             //cout<<ans/100<<endl;
            printf( "%.2lf ", ans *  1. 0 /  100);
             //cout<<ans*1.0/100<<endl;
        }
    }
    //status:acctepted
    这道题值得注意的地方
    题目给出的数据是浮点型,为了使用01背包,需要将数据放大100倍。最后输出结果时才缩小100倍。

  • 相关阅读:
    (最短路)2017 计蒜之道 复赛 D. 百度地图导航
    13 树的应用-并查集
    12 二叉树-链式存储-二叉排序树(BST)
    11 二叉树-链式存储-先序遍历、中序遍历、后序遍历和层序遍历的非递归算法实现
    10 二叉树-链式存储-递归遍历
    9 线性表-队列-链式存储
    8 线性表-循环队列-顺序存储
    操作系统-页式虚拟存储器管理系统设计
    杂谈:Windows操作系统的介绍与对Win8操作系统市场反响冷淡原因的分析
    一学期积累下来的SQL语句写法的学习
  • 原文地址:https://www.cnblogs.com/aukle/p/3235360.html
Copyright © 2011-2022 走看看