这题还是不懂啊啊啊

学术版

是不是贪心就是sort一下
by WxjzKK @ 2020-07-05 21:55:16


这不就是个变了形的01背包吗
by _5011_ @ 2020-07-05 21:56:03


01背包内层循环是倒着循环到p[i],改成这样之后倒着循环到max(p[i],q[i])不就好了
by _5011_ @ 2020-07-05 21:56:50


是的呀,可是太`蒻`的我怎么也搞不懂呀【可怜】
by WxjzKK @ 2020-07-05 21:56:59


@[WxjzKK](/user/160150) 考虑 01 背包的状态转移方程: $dp_j=\max\{dp_j,dp_{j-p_i}+v_i\}$ 要满足的是必须有 $p_i$ 才能花费掉 $p_i$。 然而现在条件变成了必须有 $q_i$ 才能花费掉 $p_i$,所以只需要修改那里就可以了
by _5011_ @ 2020-07-05 21:59:37


我搞懂了谢谢**大佬** @[Zephyr_](/user/91127)
by WxjzKK @ 2020-07-05 21:59:49


谢谢大佬万岁
by WxjzKK @ 2020-07-05 22:00:32


@[Zephyr_](/user/91127) 大佬: ```cpp #include<iostream> #include<cstdio> #include<cmath> #include<algorithm> #include<cstring> #include<iomanip> #include<string> #include<stack> #include<queue> using namespace std; int p[501],q[501],v[501],dp[5001]; int main() { int n,m; cin>>n>>m; for (int i=1;i<=n;++i) cin>>p[i]>>q[i]>>v[i]; for (int i=1;i<=n;++i) for (int j=m;j>=max(p[i],q[i]);--j) dp[j]=max(dp[j],dp[j-p[i]]+v[i]); cout<<dp[m]<<endl; return 0; } ``` 碰到 ```cpp 3 10 5 10 5 3 5 6 2 7 3 ``` 这组数据的输出是9,但实际答案确实11呀
by WxjzKK @ 2020-07-05 22:21:45


@[WxjzKK](/user/160150) 谢罪…… 1. 因为是剩余空间必须超过 q[i],而背包中转移的通常是使用的空间,所以我的那个方法其实是错的2333…… 2. 所以 q[i] 要变为 m-q[i],占用空间的范围也要变为区间 $[p[i],p[i]+q[i]]$。 3. 因为这个方程是严格从 0 开始转移,所以最后要对所有位置的 dp 值取 max。 4. 完整代码,你可以参考一下:(至少样例可过) ```cpp #include<iostream> #include<cstdio> #include<cmath> #include<algorithm> #include<cstring> #include<iomanip> #include<string> #include<stack> #include<queue> using namespace std; int p[501],q[501],v[501],dp[5001]; int main() { int n,m; cin>>n>>m; for (int i=1;i<=n;++i) cin>>p[i]>>q[i]>>v[i]; for (int i = 1;i <= n;i++) q[i] = m - q[i]; for (int i=1;i<=n;++i) for (int j=min(q[i] + p[i], m);j>=p[i];--j) dp[j]=max(dp[j],dp[j-p[i]]+v[i]); int ans = 0; for (int i = 1;i <= m;i++) ans = max(ans, dp[i]); cout << ans; return 0; } ```
by _5011_ @ 2020-07-05 22:36:18


zephyr_这个菜鸡的脑子还是不干活/kk
by _5011_ @ 2020-07-05 22:37:23


| 下一页