#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;//#include<algorithm>using namespace std;为了调用库函数max
int dp[3000005];//最多三十张每张最多1000,因为小数点后两位再乘100
int main()
{
double Q;
int N;
int i,j,k;
while(scanf("%lf%d",&Q,&N)!=EOF)
{
k=1;//新背包的下表
if(N==0)
return 0;
int q=(int)(Q*100);//将小数化成整数,因为for循环中j必须为整数
int sum[35];//去掉不符合报销规则后剩下的背包
memset(sum,0,sizeof(sum));//养成好习惯
for(i=1;i<=N;i++)
{
int m;
scanf("%d",&m);
int a[4]={0};//0不用设置三个数来分别存储A类B类C类的总额
int flag=1;//1符合规则放进新背包数组,不符合去掉
for(j=1;j<=m;j++)
{
char c;
double temp;
scanf(" %c:%lf",&c,&temp);//在输入中加入:注意题中所给是英文状态下":"
int price=(int)(temp*100);//每件物品同样扩大100
if(c=='A')
a[1]+=price;
else if(c=='B')
a[2]+=price;
else if(c=='C')
a[3]+=price;
else
{
flag=0;
break;
}
if(a[1]>60000||a[2]>60000||a[3]>60000)//某类型不符合去掉该发票
{
flag=0;
}
if(a[1]+a[2]+a[3]>100000)//总额不符合,去掉该发票
{
flag=0;
}
}
if(flag)
sum[k++]=a[1]+a[2]+a[3];//设置新背包
}
memset(dp,0,sizeof(dp));//注意设置
dp[0]=0;//好习惯
for(i=1;i<=k-1;i++)//k++比实际多1
for(j=q;j>=sum[i];j--)
dp[j]=max(dp[j],dp[j-sum[i]]+sum[i]);//该题目只给了钱的总数,所以sum[i]既是01背包中物品的价值,也是01背包的物品的体积
printf("%.2lf\n",(double)dp[q]/100);//类型转换
}
return 0;
}
HDU 1864 01背包(小数扩大)
最新推荐文章于 2023-01-14 16:19:26 发布
本文详细介绍了01背包问题的动态规划求解策略,并结合HDU 1864题目进行实例解析,探讨了在处理小数权重时的扩展方法。
摘要由CSDN通过智能技术生成