题意:现有一笔经费可以报销一定额度的发票。允许报销的发票类型包括买图书(A类)、文具(B类)、差旅(C类),要求每张发票的总额不得超过1000元,每张发票上,单项物品的价值不得超过600元。现请你编写程序,在给出的一堆发票中找出可以报销的、不超过给定额度的最大报销额。 (总发票数<=30)
思路:首先找出所有有效的发票,然后做一次01背包就行了,但是金额是两位小数,所以可以都先乘上100变成整数再去操作。
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 35;
const int maxm = 35*1005*100;
int a[maxn];
int dp[maxm];
int main(void)
{
double q;
int n;
while(cin >> q >> n)
{
if(n == 0) break;
int cur = 0;
int M = (int)(q*100);
for(int i = 0; i < n; i++)
{
int costAll = 0, costA = 0, costB = 0, costC = 0;
int k;
scanf("%d", &k);
char kind;
double x;
bool ok = 1;
for(int j = 0; j < k; j++)
{
scanf(" %c:%lf", &kind, &x);
int v = (int)(x*100);
if(kind == 'A') costA += v;
else if(kind == 'B') costB += v;
else if(kind == 'C') costC += v;
else ok = 0;
costAll += v;
}
if(ok && costA <= 60000 && costB <= 60000 && costC <= 60000 && costAll <= 100000)
a[cur++] = costAll;
}
memset(dp, 0, sizeof(dp));
for(int i = 0; i < cur; i++)
for(int j = M; j-a[i] >= 0; j--)
dp[j] = max(dp[j], dp[j-a[i]]+a[i]);
printf("%.2f\n", dp[M]/100.0);
}
return 0;
}
import java.util.Arrays;
import java.util.Scanner;
public class Main {
static final int maxn = 35;
static final int maxm = 35*1005*100;
static int a[] = new int[maxn];
static int dp[] = new int[maxm];
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
double q;
int n;
while(sc.hasNext()){
q = sc.nextDouble();
n = sc.nextInt();
if(n == 0) break;
int M = (int) (q*100);
int cur = 0;
double x;
for(int i = 0; i < n; i++)
{
int k, v, costAll = 0, costA = 0, costB = 0, costC = 0;
boolean ok = true;
k = sc.nextInt();
for(int j = 0; j < k; j++)
{
String str = sc.next();
v = (int)(100*Double.valueOf(str.substring(2, str.length())));
char kind = str.charAt(0);
if(kind == 'A') costA += v;
else if(kind == 'B') costB += v;
else if(kind == 'C') costC += v;
else ok = false;
costAll += v;
}
if(ok && costAll <= 100000 && costA <= 60000 && costB <= 60000 && costC <= 60000)
a[cur++] = costAll;
}
Arrays.fill(dp, 0);
for(int i = 0; i < cur; i++)
for(int j = M; j-a[i] >= 0; j--)
dp[j] = Math.max(dp[j], dp[j-a[i]]+a[i]);
System.out.println(String.format("%.2f", dp[M]/100.0));
}
}
}