最近由于刚开学事情很多所以久不更新(你看这个借口起得多好),再经过一番思想斗争后终于开始认真学习,希望以后博客能高产似母猪。
描述
一天晚上,小偷带了一个包偷偷进入一家人家。小偷发现那人家家里东西很多,但他看中了n个物品,这n个物品的第i个的体积为wi,价值为vi(i=1,2,……,n),包能容纳的物品的体积为c,他要从这n个物品中选出若干件放入包,使得放入包内的物品的总体积不超过c,而总价值达到最大。
输入
输入有若干组测试数据(不超过20组)。
每组测试数据有3行:其第1行上有2个整数n和c,分别是物品个数n和包所能容纳物品的体积,(n<=50,c<=500),第2行上有n个整数v1、v2、…、vn,依次是n个物品的价值,第3行上有n个整数w1、w2、…、wn,,分别是n个物品的重量。诸整数之间用一个空格分开。
输出
现对输入中的每组测试数据,输出1行:先输出“Case #:”,其中“#”是测试数据的组号(从1开始)。接着输出包能装的物品的最大价值。
我的想法
动态规划中的背包问题,在网上随便搜一搜就能找到一大堆资料、讲解和拓展。
在本题中最关键的就是这个公式
即在已装i-1个将要装第i个物体时,若能装下则取使价值最大的方法,若装不下则不装(保持相同的值)。
唯一在实际代码中困扰我许久的问题是变量的初始化。刚用c++,初始化什么的不太理解常常编译错误和出现莫名其妙的值。最后还是用for统一赋了一遍,希望能有所改进。
AC代码
#include<iostream>
#include<stdio.h>
using namespace std;
int main()
{
int n,v,k=1;
while(scanf("%d %d",&n,&v)==2) //物体总数和体积上限
{
int w[n+1],val[n+1]; //单个物体的体积和价值
w[0]=val[0]=0;
int i,j;
for(i=1;i<=n;i++)
cin>>val[i];
for(i=1;i<=n;i++)
cin>>w[i];
int a[n+1][v+1];
for(i=0;i<=n;i++)
for(j=0;j<=v;j++)
a[i][j]=0;
for(i=1;i<=n;i++)
{
for(j=v;j>=0;j--) //逆序
{
if(w[i]<=j)
{
a[i][j]=a[i-1][j]>(a[i-1][j-w[i]]+val[i])?a[i-1][j]:a[i-1][j-w[i]]+val[i];
}
else
a[i][j]=a[i-1][j];
}
}
cout<<"Case "<<k<<":"<<a[n][v]<<endl;
k++;
}
return 0;
}