题目链接:HDU 1864 最大报销额
01背包。
把张数当成背包,状态转移方程:f[j]=max(f[j],f[j-1]+v[i]),f[j]表示把j张装进背包的最大报销额。
这题这么做还是有点问题,比如这组数据:
100.00 5
1 A:5
1 B:20
1 C:24
1 A:30
1 A:60
f[3]为114,f[2]为90,f[3]超过了100.00,那么就会输出f[2]=90,但是很明显这个题最大报销额是95。不过这么写在杭电也能过。我看有人用Q*100作为背包,虽然不会错了,但是因为Q*100太大了,可能会超内存。
#include <iostream>
#include <cstring>
#include<iomanip>
using namespace std;
const int MAX_N = 30 + 3;
double money[3],dp[MAX_N],value[MAX_N];
double _max;
int n;
int main()
{
while(cin >> _max >> n,n)
{
int cnt = 0;
for(int i = 0;i < n;i++)
{
int m;
cin >> m;
memset(money,0,sizeof(money));
bool flag = true;
char a,b;
double v;
for(int j = 0;j < m;j++)
{
cin >> a >> b >> v;
if(a == 'A')
money[0] += v;
else if(a == 'B')
money[1] += v;
else if(a == 'C')
money[2] += v;
else
flag = false;
}
if(flag)
{
if(money[0] + money[1] + money[2] <= min(1000.0,_max) && money[0] <= 600.0 && money[1] <= 600.0 && money[2] <= 600.0)
value[cnt++] = money[0] + money[1] + money[2];
}
}
memset(dp,0,sizeof(dp));
for(int i = 0;i < cnt;i++)
{
for(int j = cnt;j >= 1;j--)
{
dp[j] = max(dp[j],dp[j - 1] + value[i]);
}
}
for(int i = cnt;i >= 0;i--)
{
if(dp[i] <= _max)
{
cout << fixed << setprecision(2) << dp[i] << endl;
break;
}
}
}
return 0;
}
本文介绍了一种解决HDU1864最大报销额问题的方法,使用01背包算法来求解最优报销金额。通过状态转移方程进行动态规划,并对特殊情况进行了讨论。
6万+

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



