HDU 1864 最大报销额
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 17530 Accepted Submission(s): 5141
m Type_1:price_1 Type_2:price_2 ... Type_m:price_m
其中正整数 m 是这张发票上所开物品的件数,Type_i 和 price_i 是第 i 项物品的种类和价值。物品种类用一个大写英文字母表示。当N为0时,全部输入结束,相应的结果不要输出。
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
简单的01背包 不过写完了才发现空间可以优化 - - 用bool来表示是否可以报销 找到最大值即可
需要注意的就是用%c读入的时候 - - 要先吃掉缓冲区的换行 一直没觉得题目说的2位精度是说所有的都是2位小数
-3- 不过看大家都这么写 看来题意就是这个意思了
这样的话 直接*100 换成整数就好了 - -
AC代码如下 - -
//
// HDU 1864 最大报销额
//
// Created by TaoSama on 2015-02-06
// Copyright (c) 2014 TaoSama. All rights reserved.
//
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <set>
#include <vector>
#define CLR(x) memset(x, 0, sizeof(x))
using namespace std;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const int N = 1e5 + 10;
int n, sum, dp[3500000], v[35]; //dp[j]表示报销当前额度的最大值 //其实也可以用bool来判断是否可报销
double q;
int main() {
#ifdef LOCAL
freopen("in.txt", "r", stdin);
// freopen("out.txt","w",stdout);
#endif
ios_base::sync_with_stdio(0);
while(scanf("%lf%d", &q, &n) == 2 && n) {
memset(dp,0,sizeof dp);
sum = q * 100; int ct = 0;
for(int i = 1; i <= n; ++i) {
int m; scanf("%d", &m);
int a = 0, b = 0, c = 0; bool ok = true;
while(m--) {
getchar();
char op; double x; scanf("%c:%lf", &op, &x); x *= 100;
if(op == 'A') a += x;
else if(op == 'B') b += x;
else if(op == 'C') c += x;
else ok = false;
}
if(a + b + c <= 100000 && a <= 60000 && b <= 60000
&& c <= 60000 && ok)
v[++ct] = a + b + c;
//cout<<v[ct]<<endl;
}
for(int i = 1; i <= ct; ++i)
for(int j = sum; j >= v[i]; --j)
dp[j] = max(dp[j], dp[j - v[i]] + v[i]);
printf("%.2f\n", dp[sum] / 100.0);
}
return 0;
}
3254




被折叠的 条评论
为什么被折叠?



