原题链接:https://ac.nowcoder.com/acm/problem/19990
思路:
1)很像电梯问题,升或降对应调高或调低,所以内部每次要考虑两个状态。说到内部,如何结合01背包找最大音量呢?
2)我们知道,01背包经典问题是求背包最大容量,其二维dp包括遍历物品和遍历容量两层for循环,最内层更新最优状态.
3)类比经典问题,这道题我们依旧采用两层for,外层遍历n首歌,内层遍历音量,但是每个音量不再是最大价值问题了,变成当前音量能否被演奏(true或false),结合外层for循环推出的每一个子状态的含义:
dp[i][j] : i首歌能否用j音量演奏
4)最后,稍作判断,得出答案。
using namespace std; const int N = 1010; int maxL,bgL,n; int a[60]; int dp[60][N]; // dp(i,j) 第i首歌能否用j音量来演唱 int main() { ios::sync_with_stdio(false); cin>>n>>bgL>>maxL; for (int i = 1; i <= n; i++) { cin>>a[i]; } dp[0][bgL] = 1; // 初始化 for (int i = 1; i <= n; i++) { for (int j = 0; j <= maxL; j++) { if (dp[i-1][j] && j+a[i] <= maxL) { // 能够改变的条件 dp[i][j+a[i]] = 1; } if (dp[i-1][j] && j-a[i] >= 0) { dp[i][j-a[i]] = 1; } } } int i; for (i = maxL; i >= 0; i--) { // 从后往前判断 if (dp[n][i]) { cout<<i<<endl; break; } } if (i < 0) cout<<-1<<endl; return 0; }
---------------------------------------------------------- 分 割 线 ----------------------------------------------------------
小主如果你有更好的思路和方法,请一定来评论区留言,愿相互学习和进步~
标签:遍历,int,bgL,---,牛客,音量,maxL,dp From: https://www.cnblogs.com/yumomo/p/17001101.html