zoukankan      html  css  js  c++  java
  • Codeforces 463D Gargari and Permutations

    题意:给你一个1-n不重复的 k个排列,让你求最长公共子序列

    解题思路:

    1)拓扑排序 + DP      这里可以知道,最长公共子序列必须满足里面 前后的字母  必须在任意一个序列里面都保持前后关系,所以我们可以把前后关系看成一条边。那么问题就装换成了在 有向无环图中求 最长路  ,这个问题可以用拓扑排序来解决。

    代码:

     1 // File Name: 463b.cpp
     2 // Author: darkdream
     3 // Created Time: 2015年03月10日 星期二 08时28分49秒
     4 
     5 #include<vector>
     6 #include<list>
     7 #include<map>
     8 #include<set>
     9 #include<deque>
    10 #include<stack>
    11 #include<bitset>
    12 #include<algorithm>
    13 #include<functional>
    14 #include<numeric>
    15 #include<utility>
    16 #include<sstream>
    17 #include<iostream>
    18 #include<iomanip>
    19 #include<cstdio>
    20 #include<cmath>
    21 #include<cstdlib>
    22 #include<cstring>
    23 #include<ctime>
    24 #include<queue>
    25 #define LL long long
    26 
    27 using namespace std;
    28 int dp[6][1005][1005];
    29 int a[1005];
    30 vector<int> mp[1005];
    31 int vis[1005];
    32 int ans[1005];
    33 int mx = 0 ; 
    34 int ru[1005];
    35 int n, k ;
    36 queue<int> qu;
    37 void solve()
    38 {
    39     memset(vis,0,sizeof(vis));
    40     for(int i = 1;i <= n;i ++)
    41     {
    42         if(ru[i] == 0)
    43         {
    44             qu.push(i);
    45         }
    46     }
    47     while(!qu.empty())
    48     {
    49        int tmp = qu.front();
    50        qu.pop();
    51        //printf("%d
    ",tmp);
    52        for(int i = 0  ;i < mp[tmp].size();i ++)
    53        {
    54           ru[mp[tmp][i]]--;
    55           //printf("%d %d
    ",mp[tmp][i],ru[mp[tmp][i]]);
    56           ans[mp[tmp][i]] = max(ans[tmp]+1,ans[mp[tmp][i]]);
    57           if(ru[mp[tmp][i]] == 0)
    58           {
    59               qu.push(mp[tmp][i]);
    60           }
    61        }
    62        mx = max(mx,ans[tmp]);
    63     }
    64 }
    65 int main(){
    66    scanf("%d %d",&n,&k);
    67    for(int i = 1;i <= k;i ++)
    68    {
    69       for(int j = 1;j <= n;j ++)
    70       {
    71           scanf("%d",&a[j]);
    72           for(int s = 1; s < j ;s ++)
    73           {
    74                 dp[i][a[s]][a[j]] = 1;
    75           }
    76       }
    77    }
    78    for(int i = 1;i <= n;i ++)
    79    {
    80       for(int j = 1;j <= n;j ++)
    81       {
    82         dp[0][i][j] = dp[1][i][j];
    83         for(int s = 2; s <= k ;s ++)
    84         {
    85           dp[0][i][j] = dp[0][i][j] & dp[s][i][j];
    86         }
    87         if(dp[0][i][j] ==  1)
    88         {
    89             ru[j] ++ ; 
    90             mp[i].push_back(j);
    91         }
    92       }
    93    }
    94    solve();
    95    printf("%d
    ",mx+1);
    96 return 0;
    97 }
    View Code

     2)知道了所有的前后关系以后,再对任意一个序列进行dp,dp[i] 表示 以i结尾的最长上升子序列的长度

    代码:

     1 // File Name: 463b.cpp
     2 // Author: darkdream
     3 // Created Time: 2015年03月10日 星期二 08时28分49秒
     4 
     5 #include<vector>
     6 #include<list>
     7 #include<map>
     8 #include<set>
     9 #include<deque>
    10 #include<stack>
    11 #include<bitset>
    12 #include<algorithm>
    13 #include<functional>
    14 #include<numeric>
    15 #include<utility>
    16 #include<sstream>
    17 #include<iostream>
    18 #include<iomanip>
    19 #include<cstdio>
    20 #include<cmath>
    21 #include<cstdlib>
    22 #include<cstring>
    23 #include<ctime>
    24 #include<queue>
    25 #define LL long long
    26 
    27 using namespace std;
    28 int dp[6][1005][1005];
    29 int ans[1005];
    30 int a[1005];
    31 int n , k ; 
    32 int main(){
    33    scanf("%d %d",&n,&k);
    34    for(int i = 1;i <= k;i ++)
    35    {
    36       for(int j = 1;j <= n;j ++)
    37       {
    38           scanf("%d",&a[j]);
    39           for(int s = 1; s < j ;s ++)
    40           {
    41                 dp[i][a[s]][a[j]] = 1;
    42           }
    43       }
    44    }
    45    for(int i = 1;i <= n;i ++)
    46    {
    47       for(int j = 1;j <= n;j ++)
    48       {
    49         dp[0][i][j] = dp[1][i][j];
    50         for(int s = 2; s <= k ;s ++)
    51         {
    52           dp[0][i][j] = dp[0][i][j] & dp[s][i][j];
    53         }
    54       }
    55    }
    56    int mx = 1 ; 
    57    for(int i = 1;i <= n;i ++)
    58    {
    59        ans[i] = 1 ; 
    60        int tmp = a[i];
    61        for(int j = 1;j < i  ;j ++)
    62        {
    63           if(dp[0][a[j]][tmp])
    64           {
    65             ans[i] = max(ans[i],ans[j]+1);
    66           }
    67           mx = max(mx,ans[i]);
    68        }
    69    }
    70    printf("%d
    ",mx);
    71 return 0;
    72 }
    View Code
    没有梦想,何谈远方
  • 相关阅读:
    redis基础
    Django Meta
    Django Query
    Django FileFieldManage
    Django Managers管理器
    Django 模型
    Pytables h5py
    python 高级部分
    Python和HDF 5大数据应用
    是时候放弃pipeline 模型 ?
  • 原文地址:https://www.cnblogs.com/zyue/p/4326220.html
Copyright © 2011-2022 走看看