#牛客春招刷题训练营# + 链接
这题和01背包的区别主要再可以重复拿去,思路见注释↓
#include <climits> #include <iostream> #include <vector> #define ll long long #define pre(i, j, k) for(ll i = j; i < k; i++) using namespace std;
我的快读第二个重载可以看看
/*rd*/template<typename T> inline void rd(T& bbv_value){char bbv_c = getchar();bbv_value = 0; while(bbv_c < '0' || bbv_c > '9'){bbv_c = getchar();}while(bbv_c <= '9' && bbv_c >= '0'){bbv_value = (bbv_value << 3)+(bbv_value << 1)+(bbv_c&15);bbv_c = getchar();}}/*第二个重载在这里*/template<typename T1, typename T2, typename ...Args> inline void rd(T1& bbv_1, T2& bbv_2, Args&... arg){rd(bbv_1); rd(bbv_2, arg...);}
int main() { int n, v; rd(n, v); vector<int> matter(n + 1), worthiness(n + 1); pre(i, 1, n+1) rd(matter[i], worthiness[i]); vector<int> dp(v + 1, 0), pro_two(v + 1, INT_MIN); pro_two[0] = 0; pre(i, 1, n + 1){ pre(j, matter[i], v+1){//---------把循环正序,使得dp[i]在之前已经判断过是否要拿物体i的状态(dp[j - matter[i]])的基础上再次判断拿不拿物体i dp[j] = max(dp[j], dp[j - matter[i]] + worthiness[i]); pro_two[j] = max(pro_two[j], pro_two[j - matter[i]] + worthiness[i]); } } int pro_one_ans = 0; pre(i, 0, v + 1){ pro_one_ans = max(pro_one_ans, dp[i]); } cout << pro_one_ans << endl; if (pro_two[v] < 0) cout << 0; else cout << pro_two[v]; } // 64 位输出请用 printf("%lld")