苹果
时间限制:
3000 ms | 内存限制:
65535 KB
难度:
3
-
描述
-
ctest有n个苹果,要将它放入容量为v的背包。给出第i个苹果的大小和价钱,求出能放入背包的苹果的总价钱最大值。
-
输入
- 有多组测试数据,每组测试数据第一行为2个正整数,分别代表苹果的个数n和背包的容量v,n、v同时为0时结束测试,此时不输出。接下来的n行,每行2个正整数,用空格隔开,分别代表苹果的大小c和价钱w。所有输入数字的范围大于等于0,小于等于1000。 输出
- 对每组测试数据输出一个整数,代表能放入背包的苹果的总价值。 样例输入
-
3 3 1 1 2 1 3 1 0 0
样例输出
-
2
冷静分析
这是我接触动态规划的第一道题,当时也是看了好半天也没看懂,学长讲过后,自己模拟了一遍状态转移,感觉还不错,主要思路如:苹果一个一个放,列个表格:
第一横行表示当书包容积是多少时;第一纵行表示每个苹果的重量和价值,其他单元格表示当书包容积为多大时,放入前几个苹果的最大价值
0.
1
2
3
1 1
V[1][0]=0
V[1][1]=1
V[1][2]=1
V[1][3]=1
2 1
V[2][0]=0
V[2][1]=1
V[2][2]=1
V[2][3]=2
3 1
V[3][0]=0
V[3][1]=1
V[3][2]=1
V[3][3]=2
V[i][j]=前i个苹果放入容积为j的背包的最大价值;
主要思想,如果第i个苹果的价值能装下第i个苹果的话,那么V[i][j]
就等于这个苹果的价值加上剩余空间装前i-1个苹果的最大价值再和装i-1个苹果容积为j的背包的最大价值比较,谁大就等于谁。
V[i][j]=max(第i个苹果的价值+V[i][j-第i个苹果所有的体积],V[i-1][j])
代码如下:
01.
#include <stdio.h>
02.
#include <string.h>
03.
#include <algorithm>
04.
#include <math.h>
05.
using
namespace
std;
06.
struct
keer
07.
{
08.
int
a,b;
09.
} s[1000];
10.
int
zt[1001][1001];
11.
int
main()
12.
{
13.
int
n,v;
14.
while
(
scanf
(
"%d%d"
,&n,&v)&&n,v)
15.
{
16.
for
(
int
i=1; i<=n; i++)
17.
{
18.
scanf
(
"%d%d"
,&s[i].a,&s[i].b);
19.
}
20.
for
(
int
i=0; i<=n; i++)
21.
zt[i][0]=0;
22.
for
(
int
i=0; i<=v; i++)
23.
zt[0][i]=0;
24.
for
(
int
i=1; i<=n; i++)
25.
{
26.
for
(
int
j=1; j<=v; j++)
27.
{
28.
zt[i][j]=zt[i-1][j];
29.
if
(s[i].a<=j)
30.
zt[i][j]=max(s[i].b+zt[i-1][j-s[i].a],zt[i-1][j]);
31.
}
32.
}
33.
printf
(
"%d\n"
,zt[n][v]);
34.
}
35.
return
0;
36.
}