zoukankan      html  css  js  c++  java
  • 2019 ICPC Malaysia National F(状态压缩)

    2019 ICPC Malaysia National F

    赛后补题。看了这个题解,说是状态压缩。

    以第一行的士兵为主,第二行士兵为次,即,第二行被第一行士兵匹配,更新第一行士兵的状态。

    用当前第i个士兵的状态更新第i+1个士兵的状态。

    f[i][j]:i为士兵的下标,j为第i个士兵的状态。(1<j<(1<<(e*2+1)))。

    比如e=3,二进制 j=1000011,表示第i个士兵之前包括第i个士兵,在[i-3,i+3]范围内,第二行的士兵已被匹配了下标为i-3,i+2,i+3的士兵。而f[i][1000011]记录的则是此状态的个数

    那么,第一行的i+1士兵可以 以j=1000011 可更新出f[i+1][0000111],f[i+1][001110],f[i+1][0010110],f[i+1][0100110],f[i][1000110],其中判断是否    **符合“不匹配”关系**,符合则不累加,不符合则可在状态中累加i的状态。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    #include<vector>
    #define debug printf("!") 
    using namespace std;
    typedef __int64 ll;
    const int mod=1e9+7;
    const int maxn=2e3+5;
    const int inf=0x3f3f3f3f;
    ll f[maxn][1<<10]={0};
    int cant[maxn]={0};
    inline int calleft(int x,int e)
    {
        for(int i=2*e;i>=0;i--)if((1<<i)&x)return e-i;
        return 0;
    }
    inline int calright(int x,int e)
    {
        for(int i=0;i<=2*e;i++)if((1<<i)&x)return e-i;
        return 0;
    }
    int main()
    {
        int n,e,k,i,j,u,v;
        scanf("%d%d%d",&n,&e,&k);
        for(i=1;i<=k;i++)
        {
            scanf("%d%d",&u,&v);
            if(u-v>e||v-u>e)continue;
            cant[u]|=1<<(e+u-v);
        }
        for(i=0;i<=e;i++)
        {
            if(1+e-i>n)continue;
            if((1<<i)&cant[1])continue;
            f[1][1<<i]=1;
        }
        for(i=1;i<n;i++)
        {
            for(j=1;j<1<<(e*2+1);j++)
            {
                if(i+calleft(j,e)<1)break;
                if(i+calright(j,e)>n)continue;
                v=j;
                if(v&(1<<(2*e)))v-=(1<<(2*e));
                v<<=1;
                for(u=0;u<=e*2;u++)
                {
                    if(i+1+e-u>n||i+1+e-u<1)continue;
                    if((1<<u)&v||(1<<u)&cant[i+1])continue;
                    f[i+1][v|(1<<u)]=(f[i+1][v|(1<<u)]+f[i][j])%mod;
                }
            }
        }
        ll ans=0;
        for(i=1;i<1<<(e*2+1);i++)ans=(ans+f[n][i])%mod;
        printf("%I64d
    ",ans);
    }

    2019-09-06

  • 相关阅读:
    Python之CVXOPT模块
    JavaScript之读取和写入cookie
    jQuery学习(2)ajax()使用
    JavaScript之使用AJAX(适合初学者)
    Jquery焦点图实例
    jquery-mobile表单提交问题
    程序员笔记|Spring IoC、面向切面编程、事务管理等Spring基本概念详解
    使用什么调试swoole程序
    swoole模块的编译安装:php编译安装swoole模块的代码
    TP5使用Redis处理电商秒杀
  • 原文地址:https://www.cnblogs.com/kkkek/p/11470628.html
Copyright © 2011-2022 走看看