博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Codeforces 463D Gargari and Permutations
阅读量:5274 次
发布时间:2019-06-14

本文共 3108 字,大约阅读时间需要 10 分钟。

题意:给你一个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
6 #include
7 #include
8 #include
9 #include
10 #include
11 #include
12 #include
13 #include
14 #include
15 #include
16 #include
17 #include
18 #include
19 #include
20 #include
21 #include
22 #include
23 #include
24 #include
25 #define LL long long26 27 using namespace std;28 int dp[6][1005][1005];29 int a[1005];30 vector
mp[1005];31 int vis[1005];32 int ans[1005];33 int mx = 0 ; 34 int ru[1005];35 int n, k ;36 queue
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\n",tmp);52 for(int i = 0 ;i < mp[tmp].size();i ++)53 {54 ru[mp[tmp][i]]--;55 //printf("%d %d\n",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\n",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
6 #include
7 #include
8 #include
9 #include
10 #include
11 #include
12 #include
13 #include
14 #include
15 #include
16 #include
17 #include
18 #include
19 #include
20 #include
21 #include
22 #include
23 #include
24 #include
25 #define LL long long26 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\n",mx);71 return 0;72 }
View Code

 

转载于:https://www.cnblogs.com/zyue/p/4326220.html

你可能感兴趣的文章
20140425 malloc和new不同 dynamic何时返回0
查看>>
hexo博客进阶-相册和独立域名
查看>>
【42.38%】【BZOJ 3196】二逼平衡树
查看>>
KD-tree详解
查看>>
mysql写存储过程根据时间变化增加工龄
查看>>
linux常见命令
查看>>
在Word中插入Excel对象
查看>>
进度十四
查看>>
巧用Fiddler代理来禁止资源缓存,从而达到每次都是从服务器加载最新的资源
查看>>
工资低的程序员,活该你工资低
查看>>
一步一步配置NLB(续)之深入测试
查看>>
Xcode快捷键大全
查看>>
月周报模板
查看>>
android 沉浸式状态栏
查看>>
JS中Object的一些关于原型的方法
查看>>
作业9
查看>>
如需空数组,请勿用undef赋值
查看>>
print 函数的进一步理解
查看>>
luogu1377 树的序 (线段树)
查看>>
Poj 1014
查看>>