小白是一家自行车行的董事长兼CEO兼技师兼……车行的主要业务是销售各种自行车配件或者根据客户需求组装自行车,因此在进货的时候他需要根据不同配件的销售情况来决定各种配件的进货量。同时,因为资金有限,小白还需要考虑如何使用有限的资金创造更大的利润。因为自行车配件种类繁多,人工计算相当的麻烦,于是小白决定找人帮他写个程序来解决车行的进货问题。每次进货前,小白都会列出可用于进货的总资金V(0<=V<=100,000)、当前自行车配件的期望利润率R(0<=R<=2)以及一个配件需求清单。配件需求清单包括所需要的配件种类N(0<=N<=100)以及每种配件的进货价格vi(0<=vi<=200,000)和需求量ci(0<=ci<=1000)。进货时的总进货价格不能超过可用于进货的总资金以避免财政赤字;同时也必须保证每种零件的进货量不超过这种零件的需求量,以避免货物积压。现在我们的任务是帮助小白计算出此次进货能达到的最大期望利润。
输入
题目有多组输入,以EOF结束。每组输入的第一行包含一个整数V和一个浮点数R;每组输入的第二行包含一个整数N,接下来的N行每一行包含两个整数vi和ci。
输出
每组输出包含一个浮点数(保留两位小数),表示此次进货所能达到的最大期望利润。
样例输入
1000 0.333 5 1100 2 1001 2 100 3 500 1 120 3 1000 0.5 3 100 3 500 1 200 1
样例输出
319.68 500.00
#include <stdio.h>
#include <string.h>
int main()
{
int i;
int n;
int k;
int val;
int num;
int volume;
int iCount;
int dp[100001];
int weight[100001];
float moneyRate;
while (EOF != scanf("%d%f", &volume, &moneyRate))
{
iCount = 0;
memset(dp, 0, sizeof(dp));
scanf("%d", &n);
for (i = 0; i < n; i++)
{
scanf("%d%d", &val, &num);
if (val > volume) continue;
k = 1;
while (num - k > 0)//按1 2 4 8 .。。的顺序存起来
{
weight[iCount++] = val * k;
num -= k;
k = k * 2;
}
weight[iCount++] = val * num;
}
for (i = 0; i < iCount; i++)
{
for (k = volume; k >= weight[i]; k--)//由低到高进行更新减少时间,如比4小的 1 2合起来就已经完美的覆盖了,不需要//再次判定减少时间,直接判定会tl
{
dp[k] = dp[k] > dp[k - weight[i]] + weight[i]? dp[k] : dp[k - weight[i]] + weight[i];
}
}
printf("%.2f\n", dp[volume] * moneyRate);
}
return 0;
}