链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
题目描述
你有一个背包,最多能容纳的体积是V。
现在有n个物品,第i个物品的体积为viv_ivi ,价值为wiw_iwi。
(1)求这个背包至多能装多大价值的物品?
(2)若背包恰好装满,求至多能装多大价值的物品?
输入描述:
第一行两个整数n和V,表示物品个数和背包体积。
接下来n行,每行两个数viv_ivi和wiw_iwi,表示第i个物品的体积和价值。
1≤n,V,vi,wi≤10001 \le n,V,v_i,w_i \le 10001≤n,V,vi,wi≤1000
输出描述:
输出有两行,第一行输出第一问的答案,第二行输出第二问的答案,如果无解请输出0。
输入:
3 5
2 10
4 5
1 4
输出:
14
9
答案:
#include<bits/stdc++.h>
using namespace std;
int dp[1005];
const int inf = 23456789;
int main()
{
int n , V;
cin >> n >> V;
int i , j;
int v[1005],w[1005];
for(i = 1; i <= n;i++)
{
cin >> v[i] >> w[i];
}
int ans2 = 0;
for(i = 1; i <= n;i++)
{
for(j = V;j >= v[i];j--)
{
dp[j] = max(dp[j],dp[j-v[i]]+w[i]);
}
}
cout << dp[V] << endl;
dp[0] = 0;
for(i = 1; i <= V;i++)
dp[i] = -inf;
for(i = 1; i <= n;i++)
{
for(j = V;j >= v[i];j--)
{
dp[j] = max(dp[j],dp[j-v[i]]+w[i]);
}
}
if(dp[V]<0)
dp[V] = 0;
cout << dp[V];
return 0;
}
答案中使用了动态规划的原理;在第一个双for循环中dp数组中存放了第i个物品存放或不存放时的最大值。存放时背包剩余的体积应当减去该物品的体积即j-v[i]同时dp数组中存放的物品总重量因此当加上w[i];
在第二个双for 循环中内容与第一个一致但此时应当将数组dp初始化为无情小但dp[0]==0此时若背包恰好放下则剩余空间为0此时输出时即为最优解;