题意:
现有一笔经费可以报销一定额度的发票。允许报销的发票类型包括买图书(A类)、文具(B类)、差旅(C类),要求每张发票的总额不得超过1000元,每张发票上,单项物品的价值不得超过600元。现请你编写程序,在给出的一堆发票中找出可以报销的、不超过给定额度的最大报销额。
这个题本来没啥好写的。处理一下输入数据,然后就是个01背包。然而很坑的一点就是每张发票上是一类物品总价值不能超过600。题目描述的有问题,狠狠坑了我一把。真实。
由于数据给的是浮点数,需要乘以100转成整数才可以做。所以二维的01背包会MLE。
#include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> #include <cmath> using namespace std; #define maxn 3000000 + 100 int main() { double p; int n, a[40]; int s[3]; while(~scanf("%lf%d", &p, &n) && n) { int tot = 0, m = round(p*100); for (int i = 1; i <= n; i++) { int k; scanf("%d", &k); int sum = 0; bool flag = true; memset(s, 0, sizeof(s)); for (int i = 1; i <= k; i++) { char type; double value; scanf(" %c:%lf", &type, &value); if (type != 'A' && type != 'B' && type != 'C') flag = false; else if (s[type-'A']+= round(value*100) > 60000) flag = false; sum += round(value*100); } if (flag && sum <= 100000) a[tot++] = sum; } int f[maxn]; memset(f, 0, sizeof(f)); for (int i = 0; i < tot; i++) for (int j = m; j >= a[i]; j--) f[j] = max(f[j], f[j-a[i]]+a[i]); printf("%d.%02d ", f[m]/100, f[m]%100); } }