• NOIP2015


    神奇的幻方

    Link
    模拟。

    #include<iostream> 
    using namespace std;
    int a[40][40];
    int main()
    {
        register int n,s=1,x,y;
        cin>>n;            
        while(s<=n*n)
            if(s==1) a[x=1][y=n+1>>1]=s++;
            else if(x==1&&y!=n) a[x=n][++y]=s++;
    	else if(x!=1&&y==n) a[--x][y=1]=s++;
    	else if(x==1&&y==n) a[++x][y]=s++;
    	else if(x!=1&&y!=n)
    	    if(!a[x-1][y+1]) a[--x][++y]=s++;
    	    else a[++x][y]=s++;
        for(int i=1;i<=n;++i,cout<<endl) for(int j=1;j<=n;++j) cout<<a[i][j]<<' ';
        return 0;
    }
    

    信息传递

    Link
    并查集求最小环。
    记录父亲的同时记录到根的长度,若一条边两端属于同一集合则更新最小环长度。

    #include<bits/stdc++.h>
    using namespace std;
    int read(){int x;scanf("%d",&x);return x;}
    const int N=200007;
    int ans=1e9,d[N],fa[N];
    int Find(int x)
    {
        if(x^fa[x])
        {
    	int f=fa[x];
    	fa[x]=Find(fa[x]),d[x]+=d[f];
        }
        return fa[x];
    }
    void check(int u,int v)
    {
        int x=Find(u),y=Find(v);
        if(x^y) fa[x]=y,d[u]=d[v]+1; else ans=min(ans,d[u]+d[v]+1);
    }
    int main()
    {
        int n=read(),i;
        for(i=1;i<=n;++i) fa[i]=i;
        for(i=1;i<=n;++i) check(i,read());
        printf("%d",ans);
    }
    

    斗地主

    Link
    dp预处理除了顺子以外的情况。(注意可以拆牌)
    然后暴力搜索顺子。

    #include<cstdio>
    #include<cstring>
    void min(int &a,int b){a=a<b? a:b;}
    int a[16],f[16][16][16][16][3],cnt[6],ans;
    void dp()
    {
        memset(f,0x3f,sizeof f),f[0][0][0][0][0]=0;
        for(int o=0,i,j,k,l,x;o<=13;++o)
    	for(k=0;k<=13;++k)
    	    for(i=0;i<=13;++i)
    		for(j=0;j<=13;++j)
    		    for(l=0;l<=2;++l)
    		    {
    			x=100;
    			if(i>0) min(x,f[i-1][j][k][o][l]+1);
                            if(j>0) min(x,f[i][j-1][k][o][l]+1);
                            if(k>0) min(x,f[i][j][k-1][o][l]+1);
                            if(o>0) min(x,f[i][j][k][o-1][l]+1);
                            if(l>0) min(x,f[i][j][k][o][l-1]+1);
                            if(l>1) min(x,f[i][j][k][o][l-2]+1);
    			if(i>0&&k>0) min(x,f[i-1][j][k-1][o][l]+1);
    			if(l>0&&k>0) min(x,f[i][j][k-1][o][l-1]+1);
    			if(j>0&&k>0) min(x,f[i][j-1][k-1][o][l]+1);
    			if(i>1&&o>0) min(x,f[i-2][j][k][o-1][l]+1);
                            if(i>0&&o>0&&l>0) min(x,f[i-1][j][k][o-1][l-1]+1);
                            if(o>0&&l>1) min(x,f[i][j][k][o-1][l-2]+1);
                            if(j>0&&o>0) min(x,f[i][j-1][k][o-1][l]+1);
                            if(j>1&&o>0) min(x,f[i][j-2][k][o-1][l]+1);
                            if(o>1) min(x,f[i][j][k][o-2][l]+1);
    			if(o>0) min(x,f[i+1][j][k+1][o-1][l]);
                            if(k>0) min(x,f[i+1][j+1][k-1][o][l]);
    			min(f[i][j][k][o][l],x);
    		    }
    }
    void dfs(int x)
    {
        if(x>=ans) return;
        for(int k=1,i,j,f,c;k<=3;++k)
            for(i=1;i<=12;++i)
            {
                f=1; if(k==1) c=5; else c=5-k;
                while(f&&i+c-1<=12)
                {
                    for(j=1;j<=c;++j) if(a[i+j-1]<k){f=0;break;}
                    if(!f) continue;
                    for(j=1;j<=c;++j) a[i+j-1]-=k;
                    dfs(x+1);
                    for(j=1;j<=c;++j) a[i+j-1]+=k;
                    ++c;
                }
            }
        memset(cnt,0,sizeof cnt);
        for(int i=1;i<=13;++i) ++cnt[a[i]];
        cnt[5]=a[14],min(ans,x+f[cnt[1]][cnt[2]][cnt[3]][cnt[4]][cnt[5]]);
    }
    int main()
    {
        int n,T;scanf("%d%d",&T,&n),dp();
        for(int num,col,i;T;--T)
        {
            memset(a,0,sizeof a),ans=n;
            for(i=1;i<=n;++i)
            {
                scanf("%d%d",&num,&col);
                if(!num) ++a[14];
                if(num>=3) ++a[num-2];
                if(num==1) ++a[12];
                if(num==2) ++a[13];
            }
            dfs(0),printf("%d
    ",ans);
        }
        return 0;
    }
    

    跳石头

    Link
    二分答案。

    #include<bits/stdc++.h>
    using namespace std;
    int a[100002],d,n,m,l,r,mid,ans;
    int read(){int x;scanf("%d",&x);return x;}
    int check(int x)
    {
        int num=0,now=0;
        for(int i=1;i<n+2;++i) if(a[i]-a[now]<x) ++num; else now=i;
        return num<=m;
    }
    int main()
    {
        d=read(),n=read(),m=read();
        for(int i=1;i<=n;i++) a[i]=read();
        a[n+1]=d,l=1,r=d;
        while(l<=r) mid=(l+r)>>1,check(mid)? ans=mid,l=mid+1:r=mid-1;
        cout<<ans;
        return 0;
    }
    

    子串

    Link
    (f_{i,j,k})表示考虑(A)的前(i)位,用(k)个串匹配到了(B)的第(j)位。
    那么首先有(f_{i,j,k}=f_{i-1,j,k})
    然后找到最小的(p)满足(A_{i-psim i}=B_{j-psim j})(f_{i,j,k}+=sumlimits_{o=1}^pf_{i-o,j-o,k-1})
    前缀和优化即可。

    #include<cstdio>
    int f[201][201],sum[201][201],P=1000000007;char a[1001],b[201];
    int inc(int a,int b){return a+=b,a>=P? a-P:a;}
    int main()
    {
        int n,m,K,i,j,k;
        scanf("%d%d%d%s%s",&n,&m,&K,a+1,b+1),f[0][0]=1;
        for(i=1;i<=n;++i) for(j=m;j;--j) for(k=K;k;--k) f[j][k]=inc(f[j][k],sum[j][k]=a[i]==b[j]? inc(sum[j-1][k],f[j-1][k-1]):0);
        printf("%d",f[m][K]);
    }
    

    运输计划

    Link
    二分一个(lim),然后对于所有路径长度(>lim)的计划,我们需要把它的路径上的一条边边权改为(0)
    可以通过差分将这条链上的点((lca)除外)全部(+1),然后dfs的时候还原,如果某个点的值等于需要改边的路径条数,那么说明所有路径都经过这个点到它父亲的那条边。
    根据贪心,我们选择这些边中边权最大的边一定是最优的。
    然后判断最长路径(-)上述边中的最大边权是否(le lim)即可。

    #include<bits/stdc++.h>
    #define pi pair<int,int>
    #define pb push_back
    using namespace std;
    namespace IO
    {
        char ibuf[(1<<21)+1],*iS,*iT ;
        char Get(){return (iS==iT? (iT=(iS=ibuf)+fread(ibuf,1,(1<<21)+1,stdin),(iS==iT? EOF:*iS++)):*iS++);}
        int read(){int x=0,c=Get();while(!isdigit(c))c=Get();while(isdigit(c))x=x*10+c-48,c=Get();return x;}
    }
    using namespace IO;
    int max(int a,int b){return a>b? a:b;}
    const int N=300007;
    vector<pi>E[N];int n,m,mx,cnt,x,top[N],dis[N],sz[N],son[N],fa[N],d[N],dep[N],t[N];
    struct query{int u,v,l,lca;}q[N];
    void dfs(int u,int f)
    {
        fa[u]=f,sz[u]=1,dep[u]=dep[f]+1,dis[u]=dis[f]+d[u];
        for(auto[v,w]:E[u]) if(v^f) d[v]=w,dfs(v,u),sz[u]+=sz[v],son[u]=sz[v]>sz[son[u]]? v:son[u];
    }
    void Dfs(int u,int tp){top[u]=tp;if(son[u])Dfs(son[u],tp);for(auto[v,w]:E[u]) if(v^fa[u]&&v^son[u]) Dfs(v,v);}
    int lca(int u,int v){while(top[u]^top[v]) dep[top[u]]>dep[top[v]]? u=fa[top[u]]:v=fa[top[v]];return dep[u]<dep[v]? u:v;}
    void cal(int u)
    {
        for(auto[v,w]:E[u]) if(v^fa[u]) cal(v),t[u]+=t[v];
        if(t[u]==cnt) x=max(x,d[u]);
    }
    int check(int lim)
    {
        memset(t,0,sizeof t),cnt=x=0;
        for(int i=1;i<=m;++i) if(q[i].l>lim) ++t[q[i].u],++t[q[i].v],t[q[i].lca]-=2,++cnt;
        cal(1);
        return mx-x<=lim;
    }
    int main()
    {
        n=read(),m=read();
        for(int i=1,u,v,w;i<n;++i) u=read(),v=read(),w=read(),E[u].pb(pi(v,w)),E[v].pb(pi(u,w));
        dfs(1,0),Dfs(1,1);
        for(int i=1;i<=m;++i) q[i].u=read(),q[i].v=read(),q[i].lca=lca(q[i].u,q[i].v),mx=max(mx,q[i].l=dis[q[i].u]+dis[q[i].v]-dis[q[i].lca]*2);
        int l=0,r=mx,mid;
        while(l<=r) mid=l+r>>1,check(mid)? r=mid-1:l=mid+1;
        printf("%d",l);
    }
    
  • 相关阅读:
    SNP/单核苷酸多态性分析
    非链特异性转录组测序
    什么是转录因子?
    MEME(Motif-based sequence analysis tools)使用说明
    DNA binding motif比对算法
    序列比对那点事儿
    DNA motif 搜索算法总结
    Bioconductor简介
    什么是RNA-Seq (RNA Sequencing)
    TPM、read counts、RPKM/FPKM你选对了吗?
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/11861163.html
Copyright © 2020-2023  润新知