#include<iostream>
#include<vector>
using namespace std;
int main(void){
int n = 0, m = 0, sum = 0, outmax = 0;
cin >> n >> m;
int value[n+1];
for(int i = 1; i <= n; i++){
cin >> value[i];
sum += value[i];
}
vector<int> dp(sum - m + 1,0);
for(int i = 1; i <= n; i++){
for(int j = sum - m; j >= 1; j--){
if(j>=value[i]){
dp[j] = max(dp[j],dp[j - value[i]] + value[i]);
outmax = max(outmax, dp[j]);
}
}
}
cout<<sum - outmax;
}
简单分享一下思路:
1,首先是使用01背包的思想,但这里有些不同。每个节点上的最优要用outmax手动保存一下。不是从dp数组里直接检索出来。所以我认为在本题里01背包的思想主要是用来遍历。并不是纯粹的01背包问题。
2,关于如何转化成01背包问题,可以参考其他人的文章,这里就不细说了。可以认为是先把所有书籍都放入背包,然后我们的任务是挑选一些拿出来。把放入的问题变成拿出,就可以套用01背包的思路了。
3,这里我使用了一下循环的一维dp数组,没有用二维的dp数组,这一部分可以参考一下其他人的文章。
水平有限 代码本身有不足还望指正