[HAOI2012]音量调节

题目

Description

一个吉他手准备参加一场演出。他不喜欢在演出时始终使用同一个音量,所以他决定每一首歌之前他都需要改变一次音量。在演出开始之前,他已经做好一个列表,里面写着每首歌开始之前他想要改变的音量是多少。每一次改变音量,他可以选择调高也可以调低。

音量用一个整数描述。输入文件中整数 beginLeve,代表吉他刚开始的音量,整数 maxLevel,代表吉他的最大音量。音量不能小于 0也不能大于 maxLevel。输入中还给定了 n 个整数 c_1,c_2,c_3,,cn,表示在第 i 首歌开始之前吉他手想要改变的音量是多少。

吉他手想以最大的音量演奏最后一首歌,你的任务是找到这个最大音量是多少。

Input

第一行依次为三个整数 nbeginLevel 和 maxLevel

第二行依次为 n 个整数 c_1,c_2,c_3,cn

Output

输出演奏最后一首歌的最大音量。如果吉他手无法避免音量低于 0 或者高于 maxLevel,输出 -1

Sample Input

3 5 10
5 3 7

Sample Output

10

思路

很明显是一道$dp$ 题;

我们设 $dp[i][j]$ 表示第 $i$ 首歌时,调成的音量 $j$;

那么就有转移方程 

dp[i][j]=max(dp[i][j],dp[i-1][j-a[i]])

和       

dp[i][j]=max(dp[i][j],dp[i-1][j+a[i]])

这样就$ok$ 了;

代码

#include<bits/stdc++.h>
#define re register
typedef long long ll;
using namespace std;
inline ll read()
{
    ll a=0,f=1; char c=getchar();
    while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
    while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
    return a*f;
}//快读
ll n,x,y;
ll a[101];
ll dp[1010][1010];
int main()
{
    n=read(); x=read(); y=read();
    for(re ll i=1;i<=n;i++)
        a[i]=read();//读入操作
    dp[0][x]=1;//初始化
    for(re ll i=1;i<=n;i++)
    for(re ll j=y;j>=0;j--)
    {
        if(j-a[i]>=0)//判数组下标不为0
            dp[i][j]=max(dp[i][j],dp[i-1][j-a[i]]);//转移方程
        if(j-a[i]<=y)//判下标不超过最大音量
            dp[i][j]=max(dp[i][j],dp[i-1][j+a[i]]);
//        cout<<dp[i][j]<<endl;
    }
    ll flag=0;
    for(re ll j=y;j>=0;j--)
    if(dp[n][j])
    {
        printf("%lld
",j);//输出
        flag=1;
        break;
    }
    if(!flag)
        puts("-1");
}
原文地址:https://www.cnblogs.com/wzx-RS-STHN/p/13448571.html