题目描述:
一个吉他手准备参加一场演出。他不喜欢在演出时始终使用同一个音量,所以他决定每一首歌之前他都需要改变一次音量。在演出开始之前,他已经做好一个列表,里面写着每首歌开始之前他想要改变的音量是多少。每一次改变音量,他可以选择调高也可以调低。
音量用一个整数描述。输入文件中整数 beginLevel,代表吉他刚开始的音量,整数 maxLevel,代表吉他的最大音量。音量不能小于 0 也不能大于 maxLevel。输入中还给定了 n 个整数 c1,c2,c3,⋯ ,cn,表示在第 i 首歌开始之前吉他手想要改变的音量是多少。
吉他手想以最大的音量演奏最后一首歌,你的任务是找到这个最大音量是多少。
输入格式:
第一行依次为三个整数 n,beginLevel 和 maxLevel。
第二行依次为 n 个整数 c1,c2,c3,⋯ ,cnc_1,c_2,c_3。
输出格式:
输出演奏最后一首歌的最大音量。如果吉他手无法避免音量低于 0 或者高于 maxLevel,输出 -1。
输入输出样例:
输入 #1复制
3 5 10
5 3 7
输出 #1复制
10
说明/提示:
1 ≤ n ≤ 50,1 ≤ ci ≤ maxLevel,1 ≤ maxLevel ≤ 1000,0 ≤ beginLevel ≤ maxLevel。
AC Code:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; //dp数组一维表示歌曲数目,二维表示音量 int dp[51][1001],a[51]; int n,beginlevel,maxlevel; int main() { cin>>n>>beginlevel>>maxlevel; for(int i=1;i<=n;i++) { cin>>a[i];//读入每首歌需要改变的音量 } //beginlevel为刚开始的音量 dp[0][beginlevel]=1;//所以未演凑之前就可以达到,赋值为1 for(int i=1;i<=n;i++) {//n首歌曲 for(int j=maxlevel;j>=0;j--) {//控制音量(01背包) //两个if判断满足:0<=音量<=maxlevel if(j-a[i]>=0) { //可以调低或者不调(或运算) dp[i][j]=dp[i][j]||dp[i-1][j-a[i]]; } if(j+a[i]<=maxlevel) { //可以调高或者不调(或运算) dp[i][j]=dp[i][j]||dp[i-1][j+a[i]]; } } } //任务是找到这个最大音量是多少,所以从最大音量开始循环查找 for(int i=maxlevel;i>=0;i--) { //一维等于n表示题中所说的最后一首歌 if(dp[n][i]) {//二维表示最大音量为多少 cout<<i<<endl; return 0; } } cout<<"-1"<<endl;//无法避免音量低于0或者高于maxLevel return 0; }