//当成0-1背包来做的
//思路,先转化成整数,扩大100倍,首先删除不符合条件的,然后01背包
//提交情况:Memory Limit Exceed 1次,一开始扩大了1000倍,不过我感觉还是应该扩大1000倍。
//收获:printf("%0.2lf\n",(double)dp[(int)(all*100)]/100)中如果不强制转化为double的话,前面的保留两位小数的格式不起作用
//AC Code
//6038113 2012-06-05 16:33:34 Accepted 1864 703MS 12268K 1244 B G++ chen
#include<iostream>
#include<string>
#include<sstream>
using namespace std;
int bill[35];
int kind[3];
int N,n;
int dp[3000000];
double all;
string str;
int main(){
while(cin>>all>>N&&N){
//每张发票来说
memset(bill,0,sizeof(bill));
for(int i=0;i<N;i++){
cin>>n;
memset(kind,0,sizeof(kind));
//每张发票的每一项
while(n--){
cin>>str;
char tmp=str[0];
if(tmp=='A'||tmp=='B'||tmp=='C'&&bill[i]!=-1){
stringstream ss;
ss<<str.substr(2,str.length()-2);
double d;
ss>>d;
kind[tmp-'A']+=(int)(d*100);
}
else{
bill[i]=-1;
}
}//end while
//判断每张发票的每一项
double sum=0;
if(bill[i]!=-1){
for(int j=0;j<3;j++){
if(kind[j]>60000){
bill[i]=-1;
break;
}
sum+=kind[j];
}
if(bill[i]!=-1){
if(sum>100000){
bill[i]=-1;
}
else{
bill[i]=sum;
}
}
}//end if
}//end for
//预处理完毕,开始进行背包
memset(dp,0,sizeof(dp));
for(int i=0;i<N&&bill[i]!=-1;i++){
for(int v=(int)(all*100);v>=bill[i];v--){
dp[v]=max(dp[v],dp[v-bill[i]]+bill[i]);
}
}
printf("%0.2lf\n",(double)dp[(int)(all*100)]/100);
}
return 0;
}
hdu 1864最大报销额 01背包
最新推荐文章于 2019-04-25 14:08:04 发布