今天笔试刷到了个背包问题,发现之前写的背包系列有点生硬,现在让我们重新背上“背包”,去感受小明的故事:那是个绿草如茵的早上,远处蓝色的海上飘着白色的帆…
01背包
故事背景
小明背上村里人给他缝制的“百家包”,来到了“明明闯关大舞台”!载着全村人希望的小明紧绷着耳朵,听着主持人掷地有声地念到游戏规则:“小明同学,面前的这条传送带将会依次出现n个物品,每个物品都有其价值和空间占用,你可以选择是否将该物品装进自己的背包中,最后若能得到最大价值则获胜!注意,每个物品你只有一次选择要还是不要的机会,当物品错过你的身旁时,它将永远过去!”
小明看着传送带上匀速移动的物品,汗珠立马涔出了脑门,“啊,只有一次机会啊…”“每次只给这么短的时间思考,该怎么办呢?”“诶,我会敲代码啊!”
Problem && Code
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define N 1005
#define mod 1000000007
#define INF 0x3f3f3f3f
const double eps=1e-8;
const double pi=acos(-1.0);
int dp[N][N];
int cost[N],val[N];
int main()
{
int T;
cin>>T;
while(T--){
int n,v;
cin>>n>>v;
for(int i=1;i<=n;i++) cin>>val[i];
for(int i=1;i<=n;i++) cin>>cost[i];
memset(dp,0,sizeof(dp));
for(int i=0;i<=v;i++){ //坑点:物品体积可能为0但价值大于0,
//即背包容量为0的时获得的最大价值可以非0...故i不能从1开始
for(int j=1;j<=n;j++){ //当传送带传来第j个物品时,小明是选还是不选呢?借上一次的经验!
if(i>=cost[j])
dp[i][j]=max(dp[i-cost[j]][j-1]+val[j], dp[i][j-1]);
else
dp[i][j]=dp[i][j-1];
}
}
cout<<dp[v][n]<<endl;
}
return 0;
}