- 输入:
-
每组测试数据可能有多组输入,对于每一组输入,
输入的第一行包括两个整数S(1 <= S <= 1000)和C(1<=C<=100),S代表地铁的总空间的大小,C代表v一共存储的炸药的个数。
接下来的C行每行包括两个1到100(包括1和100)的整数,分别表示这个炸药所需要的空间以及它所能产生的破坏力。
- 输出:
-
对于每组输入,输出只包括一行,这一行只包含一个整数,表示在地铁的有限的空间里转载选出的炸药,能产生的最大的破坏力。如果每个炸药的体积都很大,地铁的空间连一个炸药都装不下,输出0即可。
- 样例输入:
-
70 3 71 100 69 1 1 2
- 样例输出:
-
3
#include <stdio.h>
int max(int i,int j){
return i>j ? i:j;
}
int main(){
int c,n;
while(scanf("%d %d",&c,&n) != EOF){
int carr[101] = { 0 }; //炸弹的空间
int parr[101] = { 0 }; //炸弹的威力
int s[1000] = { 0 }; //存储当前容量,的最大威力
for(int i=1; i<=n; i++)
scanf("%d %d",&carr[i],&parr[i]);
for(int i=1; i<=n; i++){
for(int j=c; j>0; j--){
int t = 0;
if(j >= carr[i])
t = s[j-carr[i]] + parr[i];
s[j] = max(s[j],t);
}
}
printf("%d\n",s[c]);
}
return 0;
}
/**************************************************************
Problem: 1364
User: 从此醉
Language: C
Result: Accepted
Time:200 ms
Memory:908 kb
****************************************************************/
第二种实现:
下面贴出:空间复杂度n*v的Java代码,以便理解上面的代码:
public class 背包01 { public static int capsity = 10; static int n = 3; public static int weights[] = {0,3,4,5,}; private static int values[] = {0,4,5,6}; static int opts[][] = new int[n+1][capsity+1]; public static void main(String[] args) { for(int i=1; i<=n; i++){ for(int j=1; j<=capsity; j++){ if(weights[i] <= j){ //关键的一步 opts[i][j] = Math.max(opts[i-1][j], opts[i-1][j-weights[i]]+values[i]); }else opts[i][j] = opts[i-1][j]; } } for(int i=0; i<=n; i++){ for(int j=0; j<=capsity; j++){ System.out.printf("%3d",opts[i][j]); } System.out.println(); } System.out.println("最后的结果:"+opts[n][capsity]); } }
output:
0 0 0 0 0 0 0 0 0 0 0
0 0 0 4 4 4 4 4 4 4 4
0 0 0 4 5 5 5 9 9 9 9
0 0 0 4 5 6 6 9 10 11 11
最后的结果:11
3、递归实现: