一看这是一道很简单的题,写了暴力,就走了,的确仅4毫秒就AC了。但后来我以为或许BFS会更快(加之,太久没写搜索了),就回来重写了一下,不写不知道一写吓一跳,MLE了。这才仔细一想,暴力的状态转移是 O(n^2)的,但暴力的搜索是O(2^n)的,把我吓死了。看来以后写算法一定得多想啊! 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 }
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 }
一个吉他手准备参加一场演出。他不喜欢在演出时始终使用同一个音量,所以他决定每一首歌之前他都要改变一次音量。在演出开始之前,他已经做好了一个列表,里面写着在每首歌开始之前他想要改变的音量是多少。每一次改变音量,他可以选择调高也可以调低。
音量用一个整数描述。输入文件中给定整数beginLevel,代表吉他刚开始的音量,以及整数maxLevel,代表吉他的最大音量。音量不能小于0也不能大于maxLevel。输入文件中还给定了n个整数c1,c2,c3…..cn,表示在第i首歌开始之前吉他手想要改变的音量是多少。
吉他手想以最大的音量演奏最后一首歌,你的任务是找到这个最大音量是多少。
第一行依次为三个整数:n, beginLevel, maxlevel。
第二行依次为n个整数:c1,c2,c3…..cn。
输出演奏最后一首歌的最大音量。如果吉他手无法避免音量低于0或者高于maxLevel,输出-1。
1<=N<=50,1<=Ci<=Maxlevel 1<=maxlevel<=1000
0<=beginlevel<=maxlevel