zoukankan      html  css  js  c++  java
  • 搜索+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("
    ");
    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 }
  • 相关阅读:
    c语言几个字符串处理函数的简单实现
    各种类型排序的实现及比较
    随机洗牌算法Knuth Shuffle和错排公式
    两个栈实现队列
    面试杂题
    面试题——栈的压入、弹出顺序
    Codeforces 455A. Boredom
    PAT A1049. Counting Ones (30)
    Codeforces 895B. XK Segments
    Codeforces 282C. XOR and OR
  • 原文地址:https://www.cnblogs.com/twomeng/p/9509743.html
Copyright © 2011-2022 走看看