外卖(动态规划-背包DP)
题目描述
Bob 是一个重度外卖依赖者。这天他挑中了一家店,这家店总共有 n 种菜品,每种菜品限点一份,需要满 m 元钱才可配送,因此 Bob 想知道他至少需要花多少钱才能满足最低配送要求。
输入
输入共两行,第一行为两个正整数,n 和 m,第二行为 n 个正整数 ai
输出
输出一个数,满足最低配送要求所花的最少钱数。
样例输入
【样例1】 3 10 3 7 9 【样例2】 5 12 10 11 7 8 9 【样例3】 3 8 1 6 9
样例输出
【样例1】 10 【样例2】 15 【样例3】 9
提示
对于第二个样例,最低配送要求为 12 元,最优解为点 7 块和 8 块的两个菜,最少花 15元。
对于 30% 的数据,满足 n ≤ 15 。
对于 100% 的数据,满足 n ≤ 200, m ≤所有ai的和 ≤ 50000 。
思路:经典的01背包DP,但是有些小细节要注意一下,首要要先排序,先拿值比较小的,再拿大的,然后当出现大于等于m的值时,选取最小的值,附上AC代码
#include<bits/stdc++.h>
using namespace std;
int dp[205][50005] = { 0 };
int arr[205] = { 0 };
int main()
{
int n = 0; int m = 0;
cin >> n >> m;
int loop = 0;
for(int i = 1; i <= n; ++i)
{
cin >> arr[i];
loop += arr[i];
}
int res = INT_MAX;
sort(arr + 1, arr + 1 + n);
for(int i = 1; i <= n; ++i)
{
for(int j = 1; j <= loop; ++j)
{
if(j < arr[i])
dp[i][j] = dp[i - 1][j];
else
dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - arr[i]] + arr[i]);
if(dp[i][j] >= m)
res = min(res, dp[i][j]);
}
}
cout << res << endl;
return 0;
}