您的位置:首页 > 其它

hdu 1864

2016-07-17 20:40 267 查看

题目概述

给定报销额上限Q,可报销同时满足下述条件的发票:

不含A,B,C类以外的物品,单类物品总价不超过600,整张发票总价不超过1000

发票不可拆分报销,任意条件不满足则整张发票不可报销,给定N张发票,求最多报销多少钱

时限

1000ms/1000ms

输入

每组数据第一行一个正浮点数Q和一个正整数N,其后N行,每行第一个正整数i,其后i个项目,每个项目格式为type:cost,type为一大写英文字符,代表物品类别,cost为一正浮点数,代表价格,两个项目之间有一个空格,输入到N=0为止

限制

1<=N<=30;所有浮点数至多精确到小数点后2位

输出

每行一个浮点数,最大报销额,精确到小数点后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

讨论

dp,题本身不难,但原题没说清楚一些限制条件,而且这个输入格式也非常烦人,其实莫过于一个带上限的求最大子序列和,加个if就够,最多30张票,n^2也不担心超时,转移方程已经在代码中标注

看到讨论版有把这个题当背包做的,万幸浮点数小数位数有限,数据也比较水,额也尝试了一下,249MS,13456K,还是算了吧

题解状态

0MS,1720K,1145 B,C++

题解代码

#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
#define INF 0x3f3f3f3f
#define maxx(a,b) ((a)>(b)?(a):(b))
#define minn(a,b) ((a)<(b)?(a):(b))
#define MAXN 32
#define memset0(a) memset(a,0,sizeof(a))

int N;//发票数
double Q, piao[MAXN], dp[MAXN];//报销额上限 发票原始数据 dp辅助数组
double fun()
{
for (int p = 0; p < N; p++) {
int i;//单张票的项目数 i临时变量的名称之一
scanf("%d", &i);
double A = 0, B = 0, C = 0;//有效的三类物品总价
bool f = 0;//出现其他种类物品时变成true 发票作废
while (i--) {
char type;//种类
double cost;//价格
scanf(" %c:%lf", &type, &cost);
if (type == 'A')//不用switch只是因为懒得打break;
A += cost;
else if (type == 'B')
B += cost;
else if (type == 'C')
C += cost;
else
f = 1;//出现其他类别 发票作废
}
piao[p] = A + B + C;
if (f || piao[p] > 1000.0 || A > 600.0 || B > 600.0 || C > 600.0)//种类错或发票总价超限或三类物品总价超限
piao[p] = 0.0;//一分钱也不报销
}
for (int p = 0; p < N; p++)//不需要额外排序
for (int i = p; i >= 0; i--)//倒序以先用自身票值初始化dp值
if (dp[i] + piao[p] <= Q)//不能超出钱上限
dp[p] = maxx(dp[p], dp[i] + piao[p]);//重要的转移方程重要的转移方程重要的转移方程
return *max_element(dp, dp + N);//dp数组的末元素未必最大 需要额外找出最大值
}
int main(void)
{
//freopen("vs_cin.txt", "r", stdin);
//freopen("vs_cout.txt", "w", stdout);

while (~scanf("%lf%d", &Q, &N) && N) {//input
printf("%.2lf\n", fun());//input
memset0(dp);//原始数据数组会被新数据覆盖 无需清零
}
}


EOF
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: