洛谷 P1877 [HAOI2012]音量調節 (dp)
阿新 • • 發佈:2020-12-17
題目描述
一個吉他手準備參加一場演出。他不喜歡在演出時始終使用同一個音量,所以他決定每一首歌之前他都需要改變一次音量。在演出開始之前,他已經做好一個列表,裡面寫著每首歌開始之前他想要改變的音量是多少。每一次改變音量,他可以選擇調高也可以調低。
音量用一個整數描述。輸入檔案中整數beginLevel,代表吉他剛開始的音量,整數maxLevel,代表吉他的最大音量。音量不能小於00也不能大於maxLevel。輸入中還給定了n個整數c1,c2,c3,⋯,cn,表示在第ii首歌開始之前吉他手想要改變的音量是多少。
吉他手想以最大的音量演奏最後一首歌,你的任務是找到這個最大音量是多少。
輸入格式
第一行依次為三個整數n,beginLevel和maxLevel。
第二行依次為n個整數c1,c2,c3,⋯,cn。
輸出格式
輸出演奏最後一首歌的最大音量。如果吉他手無法避免音量低於0或者高於maxLevel,輸出-1
。
輸入輸出樣例
輸入 #13 5 10 5 3 7輸出 #1
10
說明/提示
1≤n≤50,1≤ci≤maxLevel,1≤maxLevel≤1000,0≤beginLevel≤maxLevel。
一道到達型的01揹包問題
用dp [ i ] [ j ]表示經過i次操作,音量能否到達 j。0表示不能,1表示能。
如果第 i - 1 次操作後可以達到 j,那麼第i次操作可以到達 j - n [ i ] 和 j + n [ i ]。當然了,也要考慮是否越界。至此,狀態轉移方程已經寫出來了。
#include<iostream> #include<cstdio> using namespace std; bool dp[55][1005]; int read() { int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); } while(ch>='0'&&ch<='9') { x=x*10+ch-'0'dp; ch=getchar(); } return x*f; } int main() { int a=read(),begin=read(),maxl=read(); int n[a+1]; for(int i=1;i<=a;i++) n[i]=read(); dp[0][begin]=1; for(int i=1;i<=a;i++) for(int j=0;j<=maxl;j++) if(dp[i-1][j]) { if(j+n[i]<=maxl) dp[i][j+n[i]]=1; if(j-n[i]>=0) dp[i][j-n[i]]=1; } for(int i=maxl;i>=0;i--) if(dp[a][i]) {cout<<i;return 0;} cout<<"-1"; return 0; }