D. Mysterious Crime

Posted mch5201314

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了D. Mysterious Crime相关的知识,希望对你有一定的参考价值。

链接

[http://codeforces.com/contest/1043/problem/D]

题意

给你一个m*n的矩阵(m<=10,n<=1e5),
每一行的数字是1到n里不同的数字
问你这m行中有多少个公共子序列

分析

用一个二维数组保存每一行的每个位置的数字的前面一个数字是什么,
然后后面用最后一行的数字和前面每一行对比,统计就好了,具体看代码就很容易理解了
还有一个组合数学的东西看下面图片就好了
技术分享图片

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e5+10;
int a[N];
ll sum[N];
int pre[12][N];
int main(){
    int n,m,i,j;
    //freopen("in.txt","r",stdin);
    while(~scanf("%d%d",&n,&m)){
        memset(sum,0,sizeof(sum)); 
        for(i=1;i<=m;i++)
        for(j=1;j<=n;j++){
            scanf("%d",&a[j]);//因为重复使用a[],所以最后存的是最后一行的值 
          if(j>1) pre[i][a[j]]=a[j-1];//第存的是i行a[j]这个数字的前面一个数字 
        }
        ll ans=n;
        for(i=2;i<=n;i++){//只需要从第二个列的数字开始就可以了,因为第一个数字前面没有数字 
         int cnt=0;
            for(j=1;j<m;j++)
                if(pre[j][a[i]]==pre[m][a[i]])
                cnt++;
            if(cnt==m-1) sum[i]+=sum[i-1]+1;//如果所有行都有公共的部分就可以加了
            //sum[i]+=sum[i-1]+1和组合数学有关,你可以想n个单位矩形挨在一起,
            //问你总共有多少个矩形是同一个问题就是个递推 
            ans+=sum[i];
        }
        printf("%lld
",ans); 
    }
    return 0;
}





以上是关于D. Mysterious Crime的主要内容,如果未能解决你的问题,请参考以下文章

CF1043D Mysterious Crime

Codeforces Round #519 D - Mysterious Crime

CodeForces 1043D Mysterious Crime 区间合并

Codeforces Beta Round #4 (Div. 2 Only) D. Mysterious Present(LIS)

攻防世界 reverse Mysterious

LightOJ 1220 Mysterious Bacteria