BZOJ 2748 音量调节
一看这是一道很简单的题,写了暴力,就走了,的确仅4毫秒就AC了。但后来我以为或许BFS会更快(加之,太久没写搜索了),就回来重写了一下,不写不知道一写吓一跳,MLE了。这才仔细一想,暴力的状态转移是 O(n^2)的,但暴力的搜索是O(2^n)的,把我吓死了。看来以后写算法一定得多想啊! dp的好处就在于可以不用算很多重复的子问题,否则就和暴力的搜索一模一样。给暴力的搜索,加个去重,加个剪枝后速度便会加快。这道题算是加深了我对dp和爆搜的理解吧!
这是dp的代码!
1 #include<cstdio> 2 #include<iostream> 3 #define rep(i,j,k) for(int i = j; i <= k; i++) 4 #define down(i,j,k) for(int i = j; i >= k; i--) 5 using namespace std; 6 bool a[55][1005] = {0}; 7 8 int read() 9 { 10 int s = 0, t = 1; char c = getchar(); 11 while( !isdigit(c) ){ 12 if( c == '-' ) t = -1; c = getchar(); 13 } 14 while( isdigit(c) ){ 15 s = s * 10 + c - '0'; c = getchar(); 16 } 17 return s * t; 18 } 19 20 int main() 21 { 22 int n = read(), begin = read(), maxl = read(); 23 a[0][begin] = 1; 24 rep(i,1,n){ 25 int x = read(); 26 rep(j,0,maxl){ 27 if( a[i-1][j] ){ 28 if( j-x >= 0 ) a[i][j-x] = 1; 29 if( j+x <= maxl ) a[i][j+x] = 1; 30 } 31 } 32 } 33 down(i,maxl,0){ 34 if( a[n][i] ){ 35 cout<<i<<endl; 36 return 0; 37 } 38 } 39 cout<<-1<<endl; 40 return 0; 41 }
这是BFS的,已改进
1 #include<cstdio> 2 #include<iostream> 3 #include<queue> 4 #define rep(i,j,k) for(int i = j; i <= k; i++) 5 #define down(i,j,k) for(int i = j; i <= k; i++) 6 using namespace std; 7 8 struct node{ 9 int sta, key; 10 node(int sta,int key):sta(sta), key(key) {}; 11 }; 12 bool used[55][1005] = {0}; 13 int read() 14 { 15 int s = 0, t = 1; char c = getchar(); 16 while( !isdigit(c) ){ 17 if( c == '-' ) t = -1; c = getchar(); 18 } 19 while( isdigit(c) ){ 20 s = s * 10 + c - '0'; c = getchar(); 21 } 22 return s * t; 23 } 24 int a[60] = {0}; 25 queue<node> q; 26 27 int main() 28 { 29 int n = read(), begin = read(), maxl = read(), ans = -1; 30 rep(i,0,n-1) a[i] = read(); 31 q.push(node(0,begin)); 32 while( !q.empty() ){ 33 node x = q.front(); q.pop(); 34 int state = x.sta, num = x.key; 35 if( state == n ){ 36 if( num > ans ) ans = num; 37 continue; 38 } 39 if( num+a[state] <= maxl && !used[state+1][num+a[state]] ){ 40 q.push(node(state+1,num+a[state])); 41 used[state+1][num+a[state]] = 1; 42 } 43 if( num-a[state] >= 0 && !used[state+1][num-a[state]] ) { 44 q.push(node(state+1,num-a[state])); 45 used[state+1][num-a[state]] = 1; 46 } 47 } 48 if( ans < 0 ) cout<<-1<<endl; 49 else cout<<ans<<endl; 50 return 0; 51 }
2748: [HAOI2012]音量调节
Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 1112 Solved: 723
[Submit][Status][Discuss]
Description
一个吉他手准备参加一场演出。他不喜欢在演出时始终使用同一个音量,所以他决定每一首歌之前他都要改变一次音量。在演出开始之前,他已经做好了一个列表,里面写着在每首歌开始之前他想要改变的音量是多少。每一次改变音量,他可以选择调高也可以调低。
音量用一个整数描述。输入文件中给定整数beginLevel,代表吉他刚开始的音量,以及整数maxLevel,代表吉他的最大音量。音量不能小于0也不能大于maxLevel。输入文件中还给定了n个整数c1,c2,c3…..cn,表示在第i首歌开始之前吉他手想要改变的音量是多少。
吉他手想以最大的音量演奏最后一首歌,你的任务是找到这个最大音量是多少。
Input
第一行依次为三个整数:n, beginLevel, maxlevel。
第二行依次为n个整数:c1,c2,c3…..cn。
Output
输出演奏最后一首歌的最大音量。如果吉他手无法避免音量低于0或者高于maxLevel,输出-1。
Sample Input
3 5 10
5 3 7
5 3 7
Sample Output
10
HINT
1<=N<=50,1<=Ci<=Maxlevel 1<=maxlevel<=1000
0<=beginlevel<=maxlevel
0<=beginlevel<=maxlevel
————————————————