原题链接
[HAOI2012] 音量调节
题目描述
一个吉他手准备参加一场演出。他不喜欢在演出时始终使用同一个音量,所以他决定每一首歌之前他都需要改变一次音量。在演出开始之前,他已经做好一个列表,里面写着每首歌开始之前他想要改变的音量是多少。每一次改变音量,他可以选择调高也可以调低。
音量用一个整数描述。输入文件中整数 b e g i n L e v e l beginLevel beginLevel,代表吉他刚开始的音量,整数 m a x L e v e l maxLevel maxLevel,代表吉他的最大音量。音量不能小于 0 0 0 也不能大于 m a x L e v e l maxLevel maxLevel。输入中还给定了 n n n 个整数 c 1 , c 2 , c 3 , ⋯ , c n c_1,c_2,c_3,\cdots,c_n c1,c2,c3,⋯,cn,表示在第 i i i 首歌开始之前吉他手想要改变的音量是多少。
吉他手想以最大的音量演奏最后一首歌,你的任务是找到这个最大音量是多少。
输入格式
第一行依次为三个整数 n n n, b e g i n L e v e l beginLevel beginLevel 和 m a x L e v e l maxLevel maxLevel。
第二行依次为 n n n 个整数 c 1 , c 2 , c 3 , ⋯ , c n c_1,c_2,c_3,\cdots,c_n c1,c2,c3,⋯,cn。
输出格式
输出演奏最后一首歌的最大音量。如果吉他手无法避免音量低于
0
0
0 或者高于
m
a
x
L
e
v
e
l
maxLevel
maxLevel,输出 -1
。
样例 #1
样例输入 #1
3 5 10
5 3 7
样例输出 #1
10
题解
开二维数组 d p [ i ] [ j ] dp[i][j] dp[i][j] 代表到第 i 首音乐的时候音量可不可以到达 j 。通过题目可以看出数据范围很小,所以直接枚举所有的音量看一下是不是能到达即可。
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1e3 + 10, mod = 998244353;
typedef long long LL;
int dp[N][N];
int a[N];
void solve()
{
int n, be, en;
cin >> n >> be >> en;
for (int i = 1; i <= n; i ++ ) cin >> a[i];
dp[0][be] = 1;
for (int i = 1; i <= n; i ++ )
{
for (int j = 0; j <= en; j ++ )
{
if (dp[i - 1][j] && j + a[i] <= en) dp[i][j + a[i]] = 1;
if (dp[i - 1][j] && j - a[i] >= 0) dp[i][j - a[i]] = 1;
}
}
for (int i = en; i >= 0; i -- )
{
if (dp[n][i])
{
cout << i;
return;
}
}
cout << -1 << '\n';
}
int main()
{
int T = 1;
// cin >> T;
while (T -- )
{
solve();
}
return 0;
}
总结:
一个和01背包差不多的用法,做题的时候要先看一下数据范围。我一开始想当然的把状态表示成第 i 首音乐要上升还是下降了,这种做法不可行。