搜索+DP专题(背包问题、N个数选K个使平方和最大且和为X、divide by three, multiple by two、全排列、组合、N皇后、jugs、掉石头迷宫、斐波那契、最大连续子序列和、最长上升子序列、非常可乐、导弹拦截系统:最长不降子序列)

机试-搜索专题

深搜

堆和栈的区别:
https://www.cnblogs.com/myblesh/archive/2012/03/14/2396409.html
定义全局变量或者自己malloc,栈的空间是有限的。

背包问题
 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #include <vector>
 5 #include <stack>
 6 #include <map>
 7 #include <string>
 8 #include <string.h>
 9 #include <algorithm>
10 #include <math.h>
11 using namespace std;
12 // 输出背包问题的最佳方案
13 const int maxn = 20000;
14 int n,v;
15 int w[maxn];
16 int c[maxn];
17 vector<int> tmp,ans;
18 int maxc;
19 void dfs(int i,int sumw,int sumc)
20 {
21     if (i == n)
22     {
23         if (sumc > maxc)
24         {
25             maxc = sumc;
26             ans = tmp; // the way of vector assign
27         }
28         return ;
29     }
30     if (sumw+w[i] <= v)
31     {
32        tmp.push_back(i);
33        dfs(i+1,sumw+w[i],sumc+c[i]);
34        tmp.pop_back();
35     }
36     dfs(i+1,sumw,sumc);
37 }
38 int main()
39 {
40     while (cin>>n>>v)
41     {
42         for (int i=0;i<n;i++)
43             cin >> w[i];
44         for (int i=0;i<n;i++)
45             cin >> c[i];
46         dfs(0,0,0);
47         for (int i=0;i<ans.size();i++)
48             cout << ans[i] << ' ';
49         cout << endl;
50         cout << maxc << endl;
51 
52     }
53 
54 
55     return 0 ;
56 }

N个数选K个使平方和最大且和为X

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #include <vector>
 5 #include <stack>
 6 #include <map>
 7 #include <string>
 8 #include <string.h>
 9 #include <algorithm>
10 #include <math.h>
11 using namespace std;
12 // 从N个数中选择K个数,使和为x的基础上平方和最大
13 const int maxn = 2000;
14 int n,k,x;
15 int maxsum;
16 vector<int> tmp,ans;
17 int a[maxn];
18 void dfs(int i,int num,int sum,int psum)
19 {
20     // i 代表第i个被选择的数,num代表一共挑选的数的个数,sum为其和,psum为平方和
21     if (i==n)
22     {
23         if (psum > maxsum && num == k && sum == x)
24         {
25             maxsum = psum;
26             ans = tmp;
27         }
28         return ;
29     }
30     dfs(i+1,num,sum,psum);
31     if (sum+a[i]<=x)
32     {
33         tmp.push_back(a[i]);
34         dfs(i+1,num+1,sum+a[i],psum+a[i]*a[i]);
35         tmp.pop_back();
36     }
37 }
38 int main()
39 {
40     while (cin>>n>>k>>x)
41     {
42         maxsum = 0;
43         for (int i=0;i<n;i++)
44             cin >> a[i];
45         dfs(0,0,0,0);
46         for (int i=0;i<ans.size();i++)
47             cout << ans[i] << ' ';
48         cout << endl;
49         cout << maxsum << endl;
50     }
51 
52 
53     return 0 ;
54 }
55 // 1.127s
56 void dfs(int i,int num,int sum,int psum)
57 {
58     // K个并且和为X时才判断
59     if (num == k && sum == x)
60     {
61         if (sum > maxsum)
62         {
63             maxsum = sum;
64             ans = tmp;
65         }
66         return ;
67     }
68     // 其他情况直接return 
69     if (i>n-1 || num > k || sum>x)
70         return ;
71     if (a[i]+sum <= x)
72     {
73         tmp.push_back(i);
74         dfs(i+1,num+1,sum+a[i],psum+a[i]*a[i]);
75         tmp.pop_back();
76     }
77     dfs(i+1,num,sum,psum);
78 }

codeforces round 479 D divide by three, multiple by two

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #include <vector>
 5 #include <stack>
 6 #include <map>
 7 #include <string>
 8 #include <string.h>
 9 #include <algorithm>
10 #include <math.h>
11 using namespace std;
12 
13 
14 int n;
15 long long a[101];
16 bool visited[101];
17 long long f[101];
18 
19 bool dfs(int &k)
20 {
21     if (k==n)
22         return true;
23     long long x = f[k-1];
24     for (int i=0;i<n;i++)
25     {
26         if (visited[i])
27             continue;
28         if ((a[i] == x/3 && (x%3==0)) || a[i] == x*2)
29         {
30             f[k++] = a[i];
31             visited[i] = true;
32             if (dfs(k)) return true;
33             visited[i] = false;
34             k--;
35         }
36     }
37     return false;
38 }
39 int main()
40 {
41 
42     int k;
43     while (cin>>n)
44     {
45         for (int i=0;i<n;i++)
46         {
47            cin >> a[i];visited[i] = false;
48         }
49         k = 0;
50         for(int i=0;i<n;i++)
51         {
52             visited[i] = true;
53             f[k++] =  a[i];
54             if (dfs(k)) break; // 只要找到一组就直接break,不用继续循环了
55             visited[i] = false;
56             k--;
57         }
58         for (int i=0;i<n;i++)
59             cout << f[i] <<' ';
60         cout << endl;
61 
62 
63 
64     }
65 
66     return 0 ;
67 }

return true / false / break 是为了在找到正确答案后立即输出而不是继续循环到末尾

解法2

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #include <vector>
 5 #include <stack>
 6 #include <map>
 7 #include <string>
 8 #include <string.h>
 9 #include <algorithm>
10 #include <math.h>
11 using namespace std;
12 
13 // divide by three, multiple by two
14 int n;
15 long long a[101];// 8B 2^64 = 1024^6 = e^18
16 vector<long long >ans;
17 bool flag,visited[101] ;
18 void dfs(int i,int sum) // i: the i th number ; sum:selected number
19 {
20     if (sum==n)
21     { 
22         for (int i=0;i<n-1;i++)
23             cout << ans[i] << ' ';
24         cout << ans[n-1]<<endl;
25         flag = true;
26         return ;
27     }
28 
29     //4 8 6 3 12 9
30     for (int j=0;j<n;j++)
31     {
32         if (i!=j && !visited[j])
33         {
34             if ((a[j]==a[i]/3 && a[i]%3==0) || a[j] == a[i]*2 )
35             {
36                 ans.push_back(a[j]);visited[j]=true;
37                 dfs(j,sum+1);
38                 if (!flag)
39                 {
40                   ans.pop_back();visited[j] = false;
41                 }
42             }
43         }
44     }
45 }
46 int main()
47 {
48    while (cin>>n)
49    {
50        for (int i=0;i<n;i++)
51        {
52          cin >> a[i];visited[i]=false;
53        }
54 
55         ans.clear();
56         flag = false;
57        for (int i=0;i<n;i++)
58        {
59            ans.push_back(a[i]);visited[i]=true;
60            dfs(i,1);
61            ans.pop_back();visited[i] = false;
62        }
63 
64    }
65 
66 
67 
68     return 0 ;
69 }

全排列

  • 10 min
 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #include <vector>
 5 #include <stack>
 6 #include <map>
 7 #include <string>
 8 #include <string.h>
 9 #include <algorithm>
10 #include <math.h>
11 using namespace std;
12 // 全排列
13 int n,sum;
14 bool visited[101];
15 vector<int> ans;
16 void dfs(int sum)
17 {
18     if (sum == n)
19     {
20         for (int i=0;i<n-1;i++)
21             cout << ans[i] <<" ";
22         cout << ans[n-1] << endl;
23         return;
24     }
25     for (int i=1;i<=n;i++)
26     {
27         if (!visited[i])
28         {
29            visited[i]= true;
30            ans.push_back(i);
31            dfs(sum+1);
32            visited[i]= false;
33            ans.pop_back();
34         }
35     }
36 }
37 int main()
38 {
39    while  (cin>>n)
40    {
41        for (int i=1;i<=n;i++)
42        {
43            visited[i] = false;
44        }
45        ans.clear();
46        dfs(0); // 选择0个元素
47    }
48 
49 
50     return 0 ;
51 }

组合 递归

  • 15min
 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #include <vector>
 5 #include <stack>
 6 #include <map>
 7 #include <string>
 8 #include <string.h>
 9 #include <algorithm>
10 #include <math.h>
11 using namespace std;
12 // 递归 求组合
13 int n,r,num; // num:selected numbers
14 vector<int > ans;
15 void dfs(int i,int num)
16 {
17     // 判断第I个数是否要被选择
18     if (i == n)
19     {
20         if (num == r)
21         {
22             for (int i=0;i<r-1;i++)
23             cout << ans[i] <<" ";
24             cout << ans[r-1] << endl;
25         }
26         return;
27     }
28     ans.push_back(i+1);
29     dfs(i+1,num+1);
30     ans.pop_back();
31 
32     dfs(i+1,num);
33 }
34 int main()
35 {
36    while  (cin>>n>>r)
37    {
38        ans.clear();
39        dfs(0,0);//
40    }
41 
42 
43     return 0 ;
44 }

组合 非递归

 1 #define _CRT_SECURE_NO_WARNINGS
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <iomanip>
 5 #include <cstring>
 6 #include <vector>
 7 #include <string>
 8 #include <queue>
 9 #include <stack>
10 #include <map>
11 #include <set>
12 
13 using namespace std;
14 
15 void permutation(int n, int m)
16 {
17     vector<int> combine;
18     stack<int> buf;
19     bool pop = false;
20     int top;
21 
22     buf.push(1);
23     combine.push_back(1);
24 
25     while (buf.size())
26     {
27         if (combine.size() == m)
28         {
29             for (int i = 0; i < m; ++i)
30             {
31                 printf("%d", combine[i]);
32                 if (i != m - 1)
33                     printf(" ");
34             }
35             printf("\n");
36             pop = true;
37         }
38 
39         top = buf.top() + 1;
40         if (top == n + 1)
41         {
42             pop = true;
43             buf.pop();
44             combine.pop_back();
45             continue;
46         }
47 
48         if (pop)
49         {
50             buf.pop();
51             combine.pop_back();
52             pop = false;
53         }
54 
55         if (top <= n)
56         {
57             buf.push(top);
58             combine.push_back(top);
59         }
60     }
61 
62 }
63 
64 int main()
65 {
66 #ifdef _DEBUG
67     freopen("data.txt", "r+", stdin);
68 #endif // _DEBUG
69 
70     int n, m, PS = 0;
71 
72     while (cin >> n >> m)
73     {
74         permutation(n, m);
75     }
76 
77 
78 
79     return 0;
80 }

组合数+判断素数

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #include <vector>
 5 #include <stack>
 6 #include <map>
 7 #include <string>
 8 #include <string.h>
 9 #include <algorithm>
10 #include <math.h>
11 using namespace std;
12 // 递归 求组合
13 int n,k,num,ans,ans_num; // num:selected numbers
14 int a[21];
15 bool visited[21];
16 
17 bool isSu(int x)
18 {
19     for (int i=2;i<sqrt(x)+1;i++)
20     {
21         if (x%i == 0)
22         {
23            return false;
24         }
25     }
26     return true;
27 
28 }
29 void dfs(int i,int num)
30 {
31     // 判断第I个数是否要被选择
32     if (i == n)
33     {
34         if (num == k && isSu(ans))
35         {
36          ans_num++;
37         }
38         return;
39     }
40     if (num+1 <= k )
41     {
42         ans += a[i+1];
43         dfs(i+1,num+1);
44         ans -= a[i+1];
45     }
46     dfs(i+1,num);
47 }
48 int main()
49 {
50    while  (cin>>n>>k)
51    {
52        for (int i=1;i<=n;i++)
53        {
54           cin >> a[i]; visited[i]=  false;
55        }
56        ans = 0;ans_num = 0;
57        dfs(0,0);
58        cout << ans_num << endl;
59    }
60 
61 
62     return 0 ;
63 }

N皇后

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #include <vector>
 5 #include <stack>
 6 #include <map>
 7 #include <string>
 8 #include <string.h>
 9 #include <algorithm>
10 #include <math.h>
11 using namespace std;
12 // N皇后问题
13 int n,num;
14 bool visited[11];
15 vector<int> ans;
16 bool flag = false;
17 bool isok(int i,int j)
18 {
19     // 判断第I行皇后能否放在J个列
20     // 1. 不可能同一行,因为I从1-n
21     // 2. 同一列
22     if (visited[j])
23         return false;
24     // 3. 对角线
25     // i,j / k, l |i-k| = |k-l| 时两个点在对角线上
26     for (int k = 1;k<i;k++)
27     {
28         if (abs(k-i) == abs(ans[k-1]-j))
29             return false;
30     }
31     return true;
32 }
33 void dfs(int i)
34 {
35     if (i==n)
36     {
37         flag = true;
38         for (int j=0;j<n-1;j++)
39             cout << ans[j] << " ";
40         cout << ans[n-1] << endl;
41         return ;
42     }
43     for (int j=1;j<=n;j++)
44     { // j : column
45         if (isok(i+1,j))
46         {
47             visited[j] = true;
48             ans.push_back(j);
49             dfs(i+1);
50             visited[j] = false;
51             ans.pop_back();
52         }
53 
54     }
55 }
56 int main()
57 {
58    while  (cin>>n)
59    {
60        ans.clear();
61        for (int i=0;i<=n;i++)
62         visited[i] = false;
63        dfs(0);
64        if (!flag)
65         cout<<"no solute!" <<endl;
66    }
67 
68 
69     return 0 ;
70 }

迷宫

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #include <vector>
 5 #include <stack>
 6 #include <map>
 7 #include <string>
 8 #include <string.h>
 9 #include <algorithm>
10 #include <math.h>
11 using namespace std;
12 // 走迷宫
13 int n,m;
14 int a[101][16];
15 struct point
16 {
17     int x,y;
18 };
19 point s,e,t;
20 
21 vector<point> ans;
22 void print()
23 {
24     for (int i=0;i<ans.size()-1;i++)
25     {
26         cout << "("<<ans[i].x<<","<<ans[i].y<<")->";
27     }
28     cout << "("<<ans[ans.size()-1].x<<","<<ans[ans.size()-1].y<<")"<<endl;
29 }
30 int dir[4][2] = {
31 0,-1,
32 -1,0,
33 0,1,
34 1,0
35 };
36 void dfs(point p)
37 { // p:当前位置
38     if (p.x == e.x && p.y == e.y)
39     {
40         print();
41         return;
42     }
43     if (p.x<1 || p.x > n || p.y < 1 || p.y > m)
44         return ; // meet border return
45     if (a[p.x][p.y] == 0)
46         return ; // meet wall return
47     for (int i=0;i<4;i++)
48     {
49         t = p;
50         // 四个方向即四个分支可以深搜
51         t.x = p.x+dir[i][0];
52         t.y = p.y+dir[i][1];
53         // 已经访问过的点再往下深搜的过程中不会再次访问,可以设为wall
54         a[p.x][p.y] = 0;
55         ans.push_back(t);
56         dfs(t);
57         a[p.x][p.y] = 1;
58         ans.pop_back();
59 
60     }
61 
62 }
63 int main()
64 {
65 
66     while (cin>>n>>m)
67     {
68         for (int i=1;i<=n;i++)
69         {
70             for (int j=1;j<=m;j++)
71             {
72                 cin >> a[i][j];
73             }
74         }
75         ans.clear();
76         cin >> s.x >> s.y;
77         cin >> e.x >> e.y;
78         ans.push_back(s);
79         dfs(s);
80 
81 
82     }
83 
84 
85     return 0 ;
86 }
  • 本地运行正确但提交不正确

jugs

  1 #include <iostream>
  2 #include <stdio.h>
  3 #include <stdlib.h>
  4 #include <vector>
  5 #include <stack>
  6 #include <map>
  7 #include <string>
  8 #include <string.h>
  9 #include <algorithm>
 10 #include <math.h>
 11 #include <queue>
 12 using namespace std;
 13 int ca,cb,n;
 14 struct node
 15 {
 16     int x,y;
 17     struct node *parent;
 18     string word;
 19 }s,e,tmp,cur;
 20 queue<node> q;
 21 vector<string> w;
 22 int main()
 23 {
 24     while (cin>>ca>>cb>>n)
 25     {
 26         while (!q.empty())
 27             q.pop();
 28         w.clear();
 29         s.x = 0;s.y = 0;s.parent = NULL;
 30         e.y = n;
 31         q.push(s);
 32         while (!q.empty())
 33         {
 34             cur = q.front();
 35             q.pop();
 36             // ÅжÏÊÇ·ñΪ×îÖÕ̬
 37             if (cur.y == e.y)
 38             {
 39                 string t = "success";
 40                 w.push_back(t);
 41                 struct node *p;p=&cur;
 42               while (p->parent!=NULL)
 43               {
 44                  w.push_back(p->word);
 45                  p = p->parent;
 46               }
 47               for (int i = w.size()-1;i>=0;i--)
 48               {
 49                   cout << w[i] << endl;
 50               }
 51             }
 52 
 53 
 54             if (cur.x < ca)
 55             {
 56                 tmp = cur;
 57                 // A is not full
 58                 tmp.x = ca;
 59                 tmp.word = "fill A";
 60                 tmp.parent = &cur;
 61                 q.push(tmp);
 62             }
 63 
 64             if (cur.y < cb)
 65             {
 66                 tmp = cur;
 67                 // B is not full
 68                 tmp.y = cb;
 69                 tmp.word = "fill B";
 70                 tmp.parent = &cur;
 71                 q.push(tmp);
 72             }
 73 
 74             if (cur.x > 0)
 75             {
 76                 tmp = cur;
 77                 // A is not empty
 78                 tmp.x = 0;
 79                 tmp.word = "empty A";
 80                 tmp.parent = &cur;
 81                 q.push(tmp);
 82             }
 83 
 84             if (cur.y > 0)
 85             {
 86                 tmp = cur;
 87                 // B is not empty
 88                 tmp.y = 0;
 89                 tmp.word = "empty B";
 90                 tmp.parent = &cur;
 91                 q.push(tmp);
 92             }
 93 
 94             if (cur.x > 0 && cur.y < ca)
 95             {
 96                 tmp = cur;
 97                 if (cur.x >= cb-cur.y) // x more than capacity of B
 98                 {
 99                     tmp.y = cb;
100                     tmp.x = cur.x - cb + cur.y;
101                 }
102                 else
103                 {
104                     tmp.y = cur.x+cur.y;
105                     tmp.x = 0;
106                 }
107                 tmp.word = "pour A B";
108                 tmp.parent = &cur;
109                 q.push(tmp);
110             }
111 
112             if (cur.y > 0 && cur.x < ca)
113             {
114                 tmp = cur;
115                 // B have water and A has place to hold
116                 if (cur.y >= ca-cur.x) // y more than capacity of A
117                 {
118                     tmp.x = ca;
119                     tmp.y = cur.y - ca + cur.x;
120                 }
121                 else
122                 {
123                     tmp.x = cur.x+cur.y;
124                     tmp.y = 0;
125                 }
126                 tmp.parent = &cur;
127                 tmp.word = "pour B A";
128                 q.push(tmp);
129             }
130         }
131     }
132     return 0 ;
133 }
  • char 型迷宫定义成int型导致爆莫名奇妙的错误。

掉石头迷宫

应该是迷宫状态更新的问题。 1.5小时

  1 #include <iostream>
  2 #include <stdio.h>
  3 #include <stdlib.h>
  4 #include <vector>
  5 #include <stack>
  6 #include <map>
  7 #include <string>
  8 #include <string.h>
  9 #include <algorithm>
 10 #include <math.h>
 11 #include <queue>
 12 using namespace std;
 13 // 掉石头迷宫问题
 14 int t1;
 15 char a[9][9],t[9][9];
 16 struct point
 17 {
 18     int x,y,t;
 19 }s,e,tmp,cur;
 20 vector<point> stone;
 21 queue<point> q;
 22 void printa(char a[9][9])
 23 {
 24    for (int i=1;i<=8;i++)
 25         {
 26             for (int j=1;j<=8;j++)
 27                 cout << a[i][j] << " ";
 28             cout << endl;
 29         }
 30 }
 31 void flush(char a[9][9]) // 石头状态刷新一次
 32 {
 33   /*  int x1,y1;
 34     for (int i=0;i<stone.size();i++)
 35     {
 36         x1 = stone[i].x;
 37         y1 = stone[i].y;
 38         a[x1][y1] = '.';
 39         if (x1+1 <=8) // 超出边界的石头则删除了
 40             a[x1+1][y1] = 'S';
 41     }
 42 
 43     */
 44     for (int i=1;i<9;i++)
 45     {
 46         for (int j=1;j<9;j++)
 47         {
 48             if (a[i][j] == 'S')
 49             {
 50                a[i+1][j] = 'S';
 51                a[i][j] = '.';
 52             }
 53         }
 54     }
 55 
 56 }
 57 int dir[9][2] =
 58 {
 59 -1,0,
 60 -1,1,
 61 0,1,
 62 1,1,
 63 1,0,
 64 1,-1,
 65 0,-1,
 66 -1,-1,
 67 0,0
 68 };
 69 bool judge(point tmp)
 70 {
 71     if (tmp.x < 1 || tmp.y >8 || tmp.y < 1 || tmp.y > 8)
 72         return false;
 73     if (a[tmp.x][tmp.y] == 'S' || t[tmp.x][tmp.y] == 'S') // 移动后所在位置有石头或移动后石头下落砸到自己
 74         return false;
 75     return true;
 76 }
 77 int main()
 78 {
 79     cin >> t1;
 80     bool flag;
 81     while (t1--)
 82     {
 83         flag = false;
 84         // 输入迷宫
 85         for (int i=1;i<=8;i++)
 86         {
 87             for (int j=1;j<=8;j++)
 88             {
 89                cin >> a[i][j]; t[i][j] = a[i][j];
 90             }
 91         }
 92 
 93         /* 存石头位置
 94         stone.clear();
 95         for (int i=1;i<9;i++)
 96         {
 97             for (int j=1;j<9;j++)
 98             {
 99                 if (a[i][j] == 'S')
100                 {
101                    tmp.x = i;tmp.y = j;
102                    stone.push_back(tmp);
103                 }
104             }
105         }
106         */
107         // 清空队列
108         while (!q.empty())
109             q.pop();
110         // 初始化队列
111         s.x = 8;s.y = 1;e.x = 1;e.y = 8;s.t = 0;
112         q.push(s);
113         while (!q.empty())
114         {
115             cur = q.front();q.pop();
116             if (cur.x == e.x && cur.y == e.y)
117             {
118                 flag = true;
119                 break;
120             }
121             flush(t);  // t是移动后的a
122             printa(t);
123             for (int i=0;i<9;i++)
124             {
125                 tmp = cur;
126                 tmp.x += dir[i][0];
127                 tmp.y += dir[i][1];
128                 tmp.t ++;
129                 if (judge(tmp))
130                 {
131                     q.push(tmp);
132                 }
133             }
134             flush(a);//a t 同步了
135             printa(a);
136 
137         }
138         if (flag)
139             cout << "Yes" << endl;
140         else
141             cout << "No" << endl;
142         getchar();
143     }
144     return 0 ;
145 }

DP

斐波那契

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #include <vector>
 5 #include <stack>
 6 #include <map>
 7 #include <string>
 8 #include <string.h>
 9 #include <algorithm>
10 #include <math.h>
11 #include <queue>
12 using namespace std;
13 
14 int fib(int n)
15 {
16     if (n==1 || n==2)
17         return 1;
18     else
19         return fib(n-1)+fib(n-2);
20 }
21 int main()
22 {
23     int n;
24     while (cin >> n)
25     {
26         cout << fib(n) << endl;
27     }
28     return 0 ;
29 }
  • n <= 30 最简单的递归,内存超限: 大量的重复的计算
  • 方法:通过空间的损耗来提高计算的速度,一维数组DP记录每个数的数值,未计算过则设置为-1。
  • 记忆化搜索 每个数仅算一遍
 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #include <vector>
 5 #include <stack>
 6 #include <map>
 7 #include <string>
 8 #include <string.h>
 9 #include <algorithm>
10 #include <math.h>
11 #include <queue>
12 using namespace std;
13 
14 int dp[32];
15 int fib(int n)
16 {
17     if (n==1 || n==2) // 递归边界
18     {
19        return 1;
20     }
21     if (dp[n]!=-1)
22         return dp[n]; // 先判断我们的缓存里面有没有,有的话直接取出否则递归计算
23     else
24     {
25         dp[n] = fib(n-1)+fib(n-2);
26         return dp[n];
27     }
28 
29 }
30 int main()
31 {
32     int n;
33     while (cin >> n)
34     {
35         for (int i=0;i<32;i++) dp[i] = -1;
36         cout << fib(n) << endl;
37     }
38     return 0 ;
39 }

最大连续子序列和

????????????????? 如何输出最大连续的子序列呢?

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #include <vector>
 5 #include <stack>
 6 #include <map>
 7 #include <string>
 8 #include <string.h>
 9 #include <algorithm>
10 #include <math.h>
11 #include <queue>
12 using namespace std;
13 
14 int dp[32];
15 bool flag[32];
16 int a[10001];
17 int main()
18 {
19     int n;
20     while (cin >> n)
21     {
22         for (int i=0;i<n;i++) 
23         {cin >> a[i];flag[i] = false;}
24         dp[0] = a[0];
25 
26         for (int i=1;i<n;i++)
27         {
28             dp[i] = max(a[i],dp[i-1]+a[i]);
29         }
30 
31 
32 
33 
34     }
35     return 0 ;
36 }
 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #include <vector>
 5 #include <stack>
 6 #include <map>
 7 #include <string>
 8 #include <string.h>
 9 #include <algorithm>
10 #include <math.h>
11 #include <queue>
12 using namespace std;
13 
14 int dp[32];
15 bool flag[32][32];
16 int a[10001];
17 int main()
18 {
19     int n;
20     while (cin >> n)
21     {
22         for (int i=0;i<n;i++)
23         {cin >> a[i];}
24         for (int i=0;i<32;i++)
25         {
26             for (int j=0;j<32;j++)
27                 flag[i][j] = false;
28         }
29         dp[0] = a[0]; flag[0][0] = true;
30 
31         for (int i=1;i<n;i++)
32         {
33             dp[i] = max(a[i],dp[i-1]+a[i]);
34             if (dp[i] == a[i])
35             {
36                 flag[i][i] = true;
37             }
38             else
39             {
40                 for (int x=0;x<i;x++)
41                     flag[i][x] = flag[i-1][x];
42                 flag[i][i] = true;
43             }
44         }
45         int k = 0;
46         int max = dp[0];
47         for (int i=1;i<n;i++)
48         {
49             if (dp[i] > max)
50             {
51                 max = dp[i]; k = i;
52             }
53         }
54         for (int i=0;i<n;i++)
55         {
56             if (flag[k][i])
57                 cout << a[i] <<" ";
58         }
59 
60 
61 
62 
63 
64     }
65     return 0 ;
66 }
  • 运行错误? 还是格式错误?
 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #include <vector>
 5 #include <stack>
 6 #include <map>
 7 #include <string>
 8 #include <string.h>
 9 #include <algorithm>
10 #include <math.h>
11 #include <queue>
12 using namespace std;
13 
14 
15 int main()
16 {
17     int n;
18     int dp[32];
19     int a[10001];
20     while (cin >> n)
21     {
22         for (int i=0;i<n;i++)
23         {cin >> a[i];dp[i] = 1;}
24 
25 
26         for (int i=1;i<n;i++)
27         {
28             for (int j=0;j<i;j++)
29             {
30                 if (a[j] < a[i])
31                 {
32                     dp[i] = max(dp[i],dp[j]+1);
33                 }
34             }
35         }
36         sort(dp,dp+n);
37         cout << dp[n-1] << endl;
38 
39 
40     }
41     return 0 ;
42 }
 
 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #include <vector>
 5 #include <stack>
 6 #include <map>
 7 #include <string>
 8 #include <string.h>
 9 #include <algorithm>
10 #include <math.h>
11 #include <queue>
12 using namespace std;
13 
14 const int maxn = 200001;
15 int a[maxn];
16 int n;
17 int dp[maxn];
18 int main()
19 {
20     while (cin>>n)
21     {
22         for (int i=0;i<n;i++)
23              cin >> a[i];
24         dp[0] = 1;
25         int ans = 0; // 最大dp值的下标
26         for (int i=1;i<n;i++)
27         {
28             for (int j=0;j<i;j++)
29             {
30                 if (a[j] == a[i]-1)
31                 {
32                     dp[i] = max(dp[i],dp[j]+1); // 找到最大的
33                 }
34             }
35             if (dp[i] > dp[ans])
36             {
37                 ans = i;
38             }
39         }
40         cout << dp[ans] << endl;
41         vector<int> p;p.clear();
42         for (int i = ans,j=0;i>=0;i--)
43         {
44             if (a[i] == a[ans]-j)
45             {
46                p.push_back(i);j++;
47             }
48 
49         }
50         for (int i=p.size()-1;i>0;i--)
51             cout << p[i]+1 <<" ";
52         cout << p[0]+1 << endl;
53 
54     }
55 
56     return 0 ;
57 }

time limited 超时了!

用map存储:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #include <vector>
 5 #include <stack>
 6 #include <map>
 7 #include <string>
 8 #include <string.h>
 9 #include <algorithm>
10 #include <math.h>
11 #include <queue>
12 using namespace std;
13 
14 const int maxn = 200001;
15 int a[maxn];
16 int n;
17 int dp[maxn];
18 map<int,int> m;
19 int main()
20 {
21     while (cin>>n)
22     {
23         m.clear();
24         for (int i=0;i<=n;i++)
25             m[i] = 0;
26         for (int i=1;i<=n;i++)
27         {
28             cin >> a[i];
29             m[a[i]] = m[a[i]-1]+1;
30         }
31         int ans = 0,k=0;
32         map<int,int>::iterator it;
33         for (it = m.begin();it !=m.end();it++)
34         {
35             if (it->second > ans)
36             {
37                 ans = it->second;
38                 k = it->first;
39             }
40         }
41         int pos = k - ans + 1;
42         cout << ans << endl;
43         for (int i=1;i<=n&&pos <= k;i++ )
44         {
45             if (a[i] == pos)
46             {
47                 cout << i <<" ";
48                 pos++;
49             }
50         }
51 
52 
53 
54     }
55 
56     return 0 ;
57 }

非常可乐

  1 #include <iostream>
  2 #include <stdio.h>
  3 #include <stdlib.h>
  4 #include <vector>
  5 #include <stack>
  6 #include <map>
  7 #include <string>
  8 #include <string.h>
  9 #include <algorithm>
 10 #include <math.h>
 11 #include <queue>
 12 using namespace std;
 13 
 14 int coco,n,m;
 15 struct status
 16 {
 17     int a,b,c,d;
 18 }s,cur,tmp;
 19 queue<status> q;
 20 const int maxn = 101;
 21 int v[maxn][maxn][maxn];
 22 void pour(int a,int b,int c,int d)
 23 {
 24     if (!v[a][b][c])
 25     {
 26         v[a][b][c] = 1;
 27         tmp.a = a;
 28         tmp.b = b;
 29         tmp.c = c;
 30         tmp.d = d+1; // 未出现的状态才倒水,并加入队列
 31         q.push(tmp);
 32     }
 33 }
 34 int bfs(int a,int b,int c,int d) // d为倒水次数,a,b,c为杯中可乐量
 35 {
 36     while (!q.empty()) q.pop();
 37     s.a = coco;s.b = s.c = s.d = 0; // 初始状态
 38     q.push(s);
 39     v[coco][0][0] = 1; // 该状态已入队过,为防止重复入队
 40     while (!q.empty())
 41     {
 42         cur = q.front();q.pop();
 43         if ((cur.a == coco/2 && cur.b == coco/2 )||(cur.a == coco/2 && cur.c == coco/2 ) || (cur.b == coco/2 && cur.c == coco/2 ) )
 44             return cur.d;
 45         //s->n:
 46         if (cur.a > 0 && cur.b < n) // a has coco and b is not full
 47             pour(cur.a - n + cur.b, n, cur.c, cur.d);
 48         //s->m;
 49         if ( cur.a > 0 && cur.c < m)
 50             pour(cur.a - m + cur.c, cur.b, m, cur.d);
 51         //n->s;
 52         if (cur.b > 0 && cur.a < coco)
 53             pour(cur.a + cur.b, 0, cur.c, cur.d);
 54         //m->s;
 55         if (cur.c > 0 && cur.a < coco )
 56             pour(cur.a + cur.c, cur.b, 0, cur.d);
 57         //n->m
 58         if (cur.b > 0 && cur.c < m)
 59         {
 60           if(cur.b > m - cur.c)
 61             pour(cur.a, cur.b - m + cur.c, m, cur.d);
 62           else
 63             pour(cur.a, 0, cur.b + cur.c, cur.d);
 64         }
 65 
 66         //m->n
 67         if (cur.c > 0 && cur.b < n)
 68         {
 69             if(cur.c > n - cur.b)
 70                 pour(cur.a, n, cur.c - n + cur.b, cur.d);
 71             else
 72                 pour(cur.a, cur.b + cur.c, 0, cur.d);
 73         }
 74 
 75     }
 76     return 0;
 77 }
 78 int main()
 79 {
 80     int ans;
 81     while (cin>>coco>>n>>m)
 82     {
 83         memset(v,0,sizeof(int)*maxn*maxn*maxn);
 84         if (coco==0)
 85             break;
 86         if (coco%2 == 1)
 87         {
 88             cout<< "NO" << endl;continue;
 89         }
 90         ans = bfs(coco,0,0,0);
 91         if ( ans > 0)
 92         {
 93             cout << ans << endl;
 94         }
 95         else
 96             cout<< "NO" << endl;
 97     }
 98 
 99 
100     return 0 ;
101 }

导弹拦截系统:最长不降子序列

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #include <vector>
 5 #include <stack>
 6 #include <map>
 7 #include <string>
 8 #include <string.h>
 9 #include <algorithm>
10 #include <math.h>
11 #include <queue>
12 using namespace std;
13 
14 const int maxn = 1001;
15 int main()
16 {
17     int n;
18     int a[maxn];
19     int dp[maxn]; // 以I为结尾的不降子序列的长度
20     while (cin>>n)
21     {
22         for (int i=0;i<n;i++)
23         {
24            cin >> a[i]; dp[i] = 1;
25         }
26         int ans = 1;
27         for (int i=1;i<n;i++)
28         {
29             for (int j=0;j<i;j++)
30             {
31                 if (a[j] < a[i])
32                 {
33                     dp[i] = max(dp[j]+1,dp[i]);
34                 }
35             }
36             if (dp[i] > ans)
37                 ans = dp[i];
38         }
39         cout <<ans<< endl;
40 
41 
42 
43     }
44     return 0 ;
45 }

猜你喜欢

转载自www.cnblogs.com/twomeng/p/9509743.html