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
代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
int dp[3000100];
int MyMax(int a,int b)
{
return (a>b?a:b);
}
int main()
{
int n,m,top;
double q;
while((scanf("%lf%d",&q,&n)!=EOF)&&(n!=0))
{
char type;
double price;
int i,j,x,a,b,c,tag,top;
int money[35];
top=(int)(q*100);
memset(dp,0,sizeof(dp));
memset(money,0,sizeof(money));
for(i=1;i<=n;i++)
{
a=b=c=tag=0;
scanf("%d",&m);
for(j=1;j<=m;j++)
{
scanf(" %c:%lf",&type,&price);
x=(int)(price*100);
if(type=='A')
{
a+=x;
}
else if(type=='B')
{
b+=x;
}
else if(type=='C')
{
c+=x;
}
else
{
tag=1;
}
}
if(tag!=1&&a+b+c<=100000&&a<=60000&&b<=60000&&c<=60000)
{
money[i]=a+b+c;
}
else
{
continue;
}
}
memset(dp,0,sizeof(dp));
for(i=1;i<=n;i++)
{
for(j=top;j>=money[i];j--)
{
dp[j]=MyMax(dp[j],dp[j-money[i]]+money[i]);
}
}
printf("%.2lf\n",dp[top]/100.0);
}
//while(1);
return (0);
}
但是,如果输入的数据有三位小数时,就不对了。
另一代码:
#include<stdio.h>
#include<algorithm>
using namespace std;
int main()
{
double m[31],dp[31];
int flag,i,j,N,n,l;
double A,B,C,Q,q,Max;
char c;
while(scanf("%lf%d",&Q,&N),N)
{
memset(dp,0,sizeof(dp));
l = 1;
for(i=0;i<N;i++)
{
scanf("%d",&n);
A=0;
B=0;
C=0;
flag=0;
while(n--)
{
scanf(" %c:%lf",&c,&q);
if(c == 'A') A+=q;
if(c == 'B') B+=q;
if(c == 'C') C+=q;
if(c!='A' && c!= 'B' && c!='C') flag = 1;
}
if(A+B+C<=1000 && A<=600 && B<= 600 && C<=600 && flag!=1 )
m[l++] = A+B+C;
}
for(i=1;i<l;i++)
{
for(j=i-1;j>=0;j--)
if(dp[j]+m[i]<=Q )
dp[i] = max(dp[i],dp[j]+m[i]); //不理解!!!
}
Max = 0;
for(i=1;i<l;i++)
if(dp[i] > Max)Max = dp[i];
printf("%.2f\n",Max);
}
}