think:
1 背包体积V:可以吃m碗汤圆
C[i]:1
W[i]:a[x]*c[x]
判断为多重背包的条件之一:每碗的汤圆必须是同一种且装满一碗,每种汤圆买的数量与每碗的该种汤圆最大容纳量并不是一一对应关系,也意味着有的种类汤圆可以吃多碗,有的可能一碗不够吃
2 转化为有限个01背包问题来解决,但是时间复杂度自己仍然需要优化,学哥说可以按2^n来优化,但自己还尚未明白,例如把12分成1,2,4,3的优化方式就属于一种很有效的优化
bLue祝你元宵节快乐!
Time Limit: 1000MS Memory Limit: 65536KB
Problem Description
元宵节到了,bLue 从超市采购了 n 种汤圆准备好好享受一下。
他买回来的 n 种汤圆,每种都有 3 个属性:单个汤圆能提供的愉悦值 a、购买数量 b、每碗最多可以容纳汤圆的个数 c。
不过,bLue 的饮食习惯略奇特,他的饭量可以一次吃 m 碗汤圆,但是每碗的汤圆必须全部是同一种汤圆且必须装满一碗(即汤圆个数等于此类汤圆的最大容纳量 c),否则他就不会吃。
那么问题来了,bLue 应该如何下这 m 碗汤圆,才能使他获得的总愉悦值最高?
Input
输入数据有多组(数据组数不超过 100),到 EOF 结束。
对于每组数据:
第 1 行包含 2 个整数 n, m (1 <= n, m <= 100),表示汤圆种类数和 bLue 最多能吃的碗数。
第 2 行包含 n 个用空格隔开的整数 ai (0 <= ai <= 100),表示每种汤圆的单个可获得的愉悦值。
第 3 行包含 n 个用空格隔开的整数 bi (0 <= bi <= 100),表示每种汤圆的购买数量。
第 4 行包含 n 个用空格隔开的整数 ci (1 <= ci <= 100),表示每种汤圆的在一碗内的最大容纳量。
Output
对于每组数据,输出 1 行,包含 1 个整数,表示 bLue 能获得的最大愉悦值。
Example Input
3 3
1 2 3
5 4 2
2 2 3
2 5
4 1
2 0
1 1
Example Output
10
8
Hint
Author
「2017年寒假集训 阶段测试赛2 - 元宵节专场」bLue
以下为accepted代码
#include <stdio.h>
#include <string.h>
#define Max(a, b) (a > b? a: b)
int main()
{
int w[10004], dp[10004];
int a[104], b[104], c[104];
int n, m, i, j;
while(scanf("%d %d", &n, &m) != EOF)
{
int flag = 0;
memset(dp, 0, sizeof(dp));
for(i = 0; i < n; i++)
{
scanf("%d", &a[i]);
}
for(i = 0; i < n; i++)
{
scanf("%d", &b[i]);
}
for(i = 0; i < n; i++)
{
scanf("%d", &c[i]);
}
for(i = 0; i < n; i++)
{
while(b[i] >= c[i])
{
b[i] -= c[i];
w[flag++] = a[i]*c[i];
}
}
for(i = 0; i < flag; i++)
{
for(j = m; j > 0; j--)
{
dp[j] = Max(dp[j], dp[j-1]+w[i]);
}
}
printf("%d\n", dp[m]);
}
return 0;
}
/***************************************************
User name: jk160630
Result: Accepted
Take time: 4ms
Take Memory: 152KB
Submit time: 2017-02-13 20:25:47
****************************************************/