题目描述
【问题描述】
有一个箱子的容量为V(V为正整数,且满足0≤V≤20000),同时有n件物品(0的体积值为正整数。
要求从n件物品中,选取若干装入箱内,使箱子的剩余空间最小。
输入:1行整数,第1个数表示箱子的容量,第2个数表示有n件物品,后面n个数分别表示这n件
物品各自的体积。
输出:1个整数,表示箱子剩余空间。
【输入输出样例】
输入:
24 6 8 3 12 7 9 7
输出:
0
状态转移方程:dp[v]=min(dp[v],dp[v-v[i]]-v[i]),其中v[i]表示每件物品的体积
dp[i]的含义:箱子剩余的最小空间,
min的第一个参数代表:不放入第i件物品时,箱子剩余的最小空间
第二个参数代表:放入第i件物品时,箱子剩余的最小空间,
为什么会有两个-v[i]呢?
原因是:第一个 -v[i] 代表 放入v[i]后箱子的容量(必须大于等于0),第二个则是放入v[i]之后箱子的剩余容量
AC代码:
#include<iostream>
#include<string>
#include<string.h>
#include<algorithm>
using namespace std;
int main()
{
int V, n; //V为总容量,v数组为每个物品的体积
while (cin >> V >> n)
{
int v[20005],dp[20005] = { 0 };
for (int i = 0; i < n; i++)
{
cin >> v[i];
}
for (int i = 0; i <= V; i++) //将dp初始化为箱子总体积
{
dp[i] = V;
}
for (int i = 0; i < n; i++) //考虑至第i个物品
{
for (int j = V; j >= v[i]; j--) //状态转移
{
dp[j] = min(dp[j], dp[j - v[i]] - v[i]);
}
}
int min_left = V;
for (int i = 0; i <= V; i++) //找出最小剩余体积
{
if (dp[i] < min_left)min_left = dp[i];
}
cout << min_left << endl;
}
return 0;
}