7.31 测试 洛谷 P1955 [NOI2015]程序自动分析 P1439 【模板】最长公共子序列

T1 洛谷 P1439 【模板】最长公共子序列

题目描述

给出1-n的两个排列P1和P2,求它们的最长公共子序列。
输入输出格式
输入格式:

第一行是一个数n,

接下来两行,每行为n个数,为自然数1-n的一个排列。

输出格式:

一个数,即最长公共子序列的长度

输入输出样例
输入样例

5
3 2 1 4 5
1 2 3 4 5

输出样例

3

说明

【数据规模】

对于50%的数据,n≤1000

对于100%的数据,n≤100000

题目分析

对于50%的测试点,我们可以用 O ( n 2 ) 的做法
LCS(x,y):
(1) LCS(x - 1,y - 1) + 1 如果Ax = By
(2) max(LCS(x – 1, y) , LCS(x, y – 1)) 如果Ax ≠ By
(3) 0 如果x = 0或者y = 0
而对于100%的测试点,我们可以这样做。因为数据为1—n的排列,我们可以这样做:
对与输进来的a[i]我们把他们的位置记录下来,比如cin>>a[i],c[a[i]]=i。(不知道该怎么说这种操作)
然后在对于输入进来的数组b[i],我们这样做,例如:x=c[b[i]]这样我们是不是可以找到b中的数字在a中的位置,然后再在lis数组中找x这个数,找到第一个>=x数的位置,然后将x放在这个位置上,然后继续做下去。
想一想为什么可以这样做?当我们用c[a[i]]=i存下a[i]的位置时,在用c[b[i]]找时其实找的是a[i]的位置找到的这个位置如果在lis数组中存有或新开一个,都可以说明他们有共同的值。并且我们可以发现,lis中的值为单调上升的,为什么?因为我们存的是位置,如果你现在有b[i]的某个数,找到他在a[i]中的位置却在b[i]的前面,那么是不是不行呢?(不知道讲清楚没,自己拿程序调试一下即可)

程序代码

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=101000;
int b[N],idx[N],n;
int read(){
    int x=0,f=1;char ch=getchar();
    while (ch<'0' || ch>'9'){if (ch=='-')f=-1;ch=getchar();}
    while ('0'<=ch && ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
    return x*f;
}
int main(){
    freopen("a.in","r",stdin);
    freopen("aa.out","w",stdout);
    n=read();
    memset(b,0x3f,sizeof(b));
    for (int i=1;i<=n;i++)
        idx[read()]=i;
    for (int i=1;i<=n;i++){
        int x=idx[read()];
        *lower_bound(b+1,b+n+1,x)=x;//二分找,STL的一种用法
        //https://blog.csdn.net/tangzhide123yy/article/details/78304457
    //如不懂lower_bound可以看一下本人博客
    }
    printf("%d",lower_bound(b+1,b+n+1,b[0])-b-1);
    return 0;
}

P1955 [NOI2015]程序自动分析

题目描述

在实现程序自动分析的过程中,常常需要判定一些约束条件是否能被同时满足。

考虑一个约束满足问题的简化版本:假设x1,x2,x3…代表程序中出现的变量,给定n个形如xi=xj或xi≠xj的变量相等/不等的约束条件,请判定是否可以分别为每一个变量赋予恰当的值,使得上述所有约束条件同时被满足。例如,一个问题中的约束条件为:x1=x2,x2=x3,x3=x4,x4≠x1,这些约束条件显然是不可能同时被满足的,因此这个问题应判定为不可被满足。

现在给出一些约束满足问题,请分别对它们进行判定。
输入输出格式
输入格式:

从文件prog.in中读入数据。

输入文件的第1行包含1个正整数t,表示需要判定的问题个数。注意这些问题之间是相互独立的。

对于每个问题,包含若干行:

第1行包含1个正整数n,表示该问题中需要被满足的约束条件个数。接下来n行,每行包括3个整数i,j,e,描述1个相等/不等的约束条件,相邻整数之间用单个空格隔开。若e=1,则该约束条件为xi=xj;若�e=0,则该约束条件为xi≠xj;

输出格式:

输出到文件 prog.out 中。

输出文件包括t行。

输出文件的第 k行输出一个字符串“ YES” 或者“ NO”(不包含引号,字母全部大写),“ YES” 表示输入中的第k个问题判定为可以被满足,“ NO” 表示不可被满足。

输入输出样例
输入样例#1: 复制

2
2
1 2 1
1 2 0
2
1 2 1
2 1 1

输出样例#1: 复制

NO
YES

输入样例#2: 复制

2
3
1 2 1
2 3 1
3 1 1
4
1 2 1
2 3 1
3 4 1
1 4 0

输出样例#2: 复制

YES
NO

说明

【样例解释1】

在第一个问题中,约束条件为:x1=x2,x1≠x2。这两个约束条件互相矛盾,因此不可被同时满足。

在第二个问题中,约束条件为:x1=x2,x1=x2。这两个约束条件是等价的,可以被同时满足。

【样例说明2】

在第一个问题中,约束条件有三个:x1=x2,x2=x3,x3=x1。只需赋值使得x1=x1=x1,即可同时满足所有的约束条件。

在第二个问题中,约束条件有四个:x1=x2,x2=x3,x3=x4,x4≠x1。由前三个约束条件可以推出x1=x2=x3=x4,然而最后一个约束条件却要求x1≠x4,因此不可被满足。

简单做法,直接并查集就行,可以拿到部分分。然后满分做法就是直接离散一下,就可以做了

程序代码

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define maxn 10000005
using namespace std;
struct arr{
    int x,y,e;
}a[100005];
int t,n,tot,tmp[maxn];
int fa[maxn];
inline int read(){
    int x=0,w=1;char ch;
    while(ch!='0'&&(ch<'0'||ch>'9')) ch=getchar();
    if(ch=='-') w=-1,ch=getchar();
    while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch-48),ch=getchar();
    return x*w;
}
inline int cmp(arr xx,arr yy) { return xx.e>yy.e; }
int gf(int x){return x==fa[x]?x:fa[x]=gf(fa[x]);}
int main(){
    freopen("c.in","r",stdin);
    freopen("c.out","w",stdout);
    t=read();
    while (t--){
        n = read();
        tot = 0;
        for (register int i=1;i<=n;i++){
            a[i].x=read();a[i].y=read();a[i].e=read();
            tmp[++tot]=a[i].x;tmp[++tot]=a[i].y;
        }
        sort(a+1,a+n+1,cmp);
        sort(tmp+1,tmp+1+tot);
        tot=unique(tmp+1,tmp+tot+1)-(tmp+1);//STL中的合并,用法问度娘吧。也可以自己手打
        for (register int i=1;i<=tot;i++) fa[i]=i;
        bool ok=true;
        for (register int i=1;i<=n;i++){
            a[i].x=lower_bound(tmp+1,tmp+tot+1,a[i].x)-tmp;//离散,用法见上文链接
            a[i].y=lower_bound(tmp+1,tmp+tot+1,a[i].y)-tmp;//离散
            if (a[i].e) fa[gf(a[i].x)]=gf(a[i].y);
            else if (gf(a[i].x)==gf(a[i].y)) { ok = false; break; }
        }
        if (ok) printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/tangzhide123yy/article/details/81304609
今日推荐