zoukankan      html  css  js  c++  java
  • AT2161 シャッフル / Shuffling

    传送门

    其实有一个显然的性质嘛:对于每个数,其实只要考虑它最右能被换到的位置就好了
    然后设(f[i][j])表示已经处理完了前(i-1)位,当前还有(j)(1)可以自由支配(注意这里说的是当前可以自由支配,不是总共可以自由支配的(1)
    代码:

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    void read(int &x) {
        char ch; bool ok;
        for(ok=0,ch=getchar(); !isdigit(ch); ch=getchar()) if(ch=='-') ok=1;
        for(x=0; isdigit(ch); x=x*10+ch-'0',ch=getchar()); if(ok) x=-x;
    }
    #define rg register
    const int maxn=3010,mod=1e9+7;
    char ch[maxn];
    int n,m,f[maxn][maxn],tot,sum[maxn],las[maxn];
    int add(int x,int y){return x+y>=mod?x+y-mod:x+y;}
    int main()
    {
        read(n),read(m);scanf("%s",ch+1);
        for(rg int i=1;i<=n+1;i++){
            sum[i]=sum[i-1],las[i]=i;
            if(ch[i]=='1')tot++,sum[i]++;
        }
        for(rg int i=1,x,y;i<=m;i++)read(x),read(y),las[x]=max(las[x],y);
        for(rg int i=1;i<=n+1;i++)las[i]=max(las[i],las[i-1]);
        f[1][sum[las[1]]]=1;
        for(rg int i=1;i<=n;i++)
            for(rg int j=0;j<=tot;j++)
                if(f[i][j]){
                    int a=las[i],b=las[i+1];
                    if(j)f[i+1][j+sum[b]-sum[a]-1]=add(f[i+1][j+sum[b]-sum[a]-1],f[i][j]);
                    if(las[i]+1-i-j)f[i+1][j+sum[b]-sum[a]]=(f[i+1][j+sum[b]-sum[a]],f[i][j]);
            }
        printf("%d
    ",f[n+1][0]);
    }
    
  • 相关阅读:
    【洛谷P6835】线形生物
    【洛谷P2679】子串
    【洛谷P5072】盼君勿忘
    【洛谷P3312】数表
    【洛谷P1447】能量采集
    【洛谷P2257】YY的GCD
    【洛谷P4318】完全平方数
    【AT2300】Snuke Line
    window.showModalDialog
    js typeof
  • 原文地址:https://www.cnblogs.com/lcxer/p/10749059.html
Copyright © 2011-2022 走看看