codeforces 463D Gargari and Permutations(dp)

题目

参考网上的代码的、、、

//要找到所有序列中的最长的公共子序列,
//定义状态dp[i]为在第一个序列中前i个数字中的最长公共子序列的长度,
//状态转移方程为dp[i]=max(dp[i],dp[j]+1); j<i

//先预处理出两个数在所有序列中的位置关系,
//例如两个数a和b,只要在任意一个序列中a在b的后面,则记after[a][b]=1。

//在递推的时候如果!after[a][b],则进行状态转移。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;

int a[6][1010];
int after[1010][1010];
int dp[1010];
int main () {
    int n,k;
    scanf("%d%d",&n,&k);
    int ii=0;
    for(int i=0;i<k;i++)
    {
        for(int j=0;j<n;j++)
        {
            scanf("%d",&a[i][j]);
        }
    }
    memset(after,0,sizeof(after));
    memset(dp,0,sizeof(dp));
    for(int i=0;i<k;i++)
    {
        for(int j=0;j<n;j++)
        {
            for(int k=j+1;k<n;k++)
            {
                after[a[i][k]][a[i][j]]=1; //存在 k在j后面
            }
        }
    }

    int ans=0;

    //直接对1~n进行状态转移不可以
    //要根据第一行来dp
    for(int i=0;i<n;i++)
    {
        dp[i]=1;
        for(int j=0;j<i;j++)
        {
            if(after[a[0][j]][a[0][i]]==0)dp[i]=max(dp[i],dp[j]+1);
        }
        ans=max(dp[i],ans);
    }
    printf("%d\n",ans);
    return 0 ;
}        

时间: 2025-01-01 20:41:13

codeforces 463D Gargari and Permutations(dp)的相关文章

Codeforces 463D. Gargari and Permutations【DP】

题目大意: 给出1~n的k个排列(2<=k<=5),要求其中的最长公共子序列. 做法: 算是不难的DP,dp[i]表示以i为结尾的最长公共子序列的长度,由于每个数在一个排列中只可能出现一次,我们用一个二维数组pos[i][j]表示数字j在第i行出现在第几个位置,再用一个数组cnt[i] 记录i出现了多少次:当第i个数出现了k次之后,说明能够以该数为结尾构成公共子序列,那么dp[i]=max(dp[j]+1),其中i,j满足pos[u][i]>pos[u][j](1<=u<=k

Codeforces 463D Gargari and Permutations(求k个序列的LCS)

题目链接:http://codeforces.com/problemset/problem/463/D 题目大意:给你k个序列(2=<k<=5),每个序列的长度为n(1<=n<=1000),每个序列中的数字分别为1~n,求着k个序列的最长公共子序列是多长?解题思路:由于每个序列的数字分别为1~n即各不相同,所以可以用pos[i][j]记录第i个序列中j的位置.设dp[i]表示以i结尾的最长公共子序列长度,那么我们可以按顺序遍历第一个序列的位置i,再在第一个序列中枚举位置j(j<

CF 463D Gargari and Permutations [dp]

给出一个长为n的数列的k个排列(1?≤?n?≤?1000; 2?≤?k?≤?5).求这个k个数列的最长公共子序列的长度 dp[i]=max{dp[j]+1,where j<i 且j,i相应的字符在k个排列中都保持同样的相对位置} #include <iostream> #include <vector> #include <cstring> #include <cstdio> #include <cmath> #include <al

CF463D Gargari and Permutations dp

考试 T2,推一推发现可以转换成一个 dp 模型. code: #include <bits/stdc++.h> #define N 1004 using namespace std; void setIO(string s) { string in=s+".in"; string out=s+".out"; freopen(in.c_str(),"r",stdin); freopen(out.c_str(),"w"

Codeforces 360C Levko and Strings dp

题目链接:点击打开链接 题意: 给定长度为n的字符串s,常数k 显然s的子串一共有 n(n-1)/2 个 要求找到一个长度为n的字符串t,使得t对应位置的k个子串字典序>s #include<stdio.h> #include<iostream> #include<string.h> #include<algorithm> #include<vector> #include<set> using namespace std; #

CodeForces 30C Shooting Gallery 简单dp

题目链接:点击打开链接 给定n个气球 下面n行 x y t val 表示气球出现的坐标(x,y) 出现的时刻t,气球的价值val 枪每秒移动1个单位的距离 问: 射击的最大价值,开始时枪瞄准的位置任意. 思路: dp一下.. #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <math.h> #include <set

Codeforces 459E Pashmak and Graph(dp+贪心)

题目链接:Codeforces 459E Pashmak and Graph 题目大意:给定一张有向图,每条边有它的权值,要求选定一条路线,保证所经过的边权值严格递增,输出最长路径. 解题思路:将边按照权值排序,每次将相同权值的边同时加入,维护每个点作为终止点的最大长度即可. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 3

codeforces 149D - Coloring Brackets (区间dp)

题目大意: 给出一组合法的括号. 括号要么不涂颜色,要么就涂上红色或者绿色. 匹配的括号只能有一个有颜色. 两个相邻的括号不能有相同的颜色. 思路分析: 因为是一个合法的括号序列. 所以每个括号与之匹配的位置是一定的. 那么就可以将这个序列分成两个区间. (L - match[L] )  (match[L]+1, R) 用递归先处理小区间,再转移大区间. 因为条件的限制,所以记录区间的同时,还要记录区间端点的颜色. 然后就是一个递归的过程. #include <cstdio> #include

codeforces A. Slightly Decreasing Permutations 题解

Permutation p is an ordered set of integers p1,??p2,??...,??pn, consisting of n distinct positive integers, each of them doesn't exceed n. We'll denote the i-th element of permutation p as pi. We'll call number n the size or the length of permutation