• POJ 2441 Arrange the Bulls(状态压缩DP)


    题意很简单,n头牛,m个位置,每头牛有各自喜欢的位置,问安排这n头牛使得每头牛都在各自喜欢的位置有几种安排方法。

    2000MS代码:

    #include <cstdio>
    #include <cstring>
    int dp[(1<<20)+2];
    int one[(1 << 20) + 2];
    //用来数出状态为i时1的个数,具体到这个题中就是
    //状态为i时有多少头牛已经安排好牛棚
    void CountOne(int m)
    {
        for(int i=0; i< (1 << m); ++i)
        {
            int num=0;
            for(int j=0; j< m; ++j)
            {
                if( (i & (1 << j)) != 0)//i的第j位置是否为一
                    ++num;
            }
            one[i] = num;
        }
    }
    int main()
    {
    //    freopen("in.cpp","r",stdin);
        int n,m;
        scanf("%d%d",&n,&m);
        CountOne(m);
        memset(dp,0,sizeof(dp));
        dp[0] = 1; //一头牛都没有安排,状态为0的满足条件的方案数为1
        for(int i=1; i<=n; ++i)
        {
            int cnt; //每头牛喜欢住的牛棚数
            scanf("%d",&cnt);
            while(cnt--)
            {
                int k; //该牛棚编号
                scanf("%d",&k);
                --k;//使得牛棚编号为 0 ~ m-1
                for(int j=0; j< (1 << m); ++j)
                {
                    if((j & (1 << k)) != 0 && one[j] == i) //这个状态已经安排好了i头牛,且第k个牛棚安排的是第i头牛
                        dp[j] += dp[j-(1<<k)];
                }
            }
        }
        // 最终结果为安排了n头牛的状态满足条件的方案数的总和
        int ans=0;
        for(int j=0; j< (1 << m ); ++j)
        {
            if(one[j] == n)
            {
                ans += dp[j];
            }
        }
        printf("%d
    ",ans);
        return 0;
    }
    View Code

    90MS

    #include <stdio.h>
    #include <string.h>
    
    int map[25][25];
    int now[(1<<20)+5];
    
    int main()
    {
        int i,j,n,m,k,x,p,ret;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            memset(map,0,sizeof(map));
            for (i=0;i<n;i++)
            {
                scanf("%d",&k);
                while(k--)
                {
                    scanf("%d",&x);
                    x--;//0~m-1编号
                    map[i+1][x]=1;
                }
            }
            if (n>m)
            {
                printf("0
    ");
                continue;
            }
            memset(now,0,sizeof(now));
            now[0]=1;
            for (i=0;i<n;i++)
            {
                for (j=(1<<m)-1;j>=0;j--)
                {
                    if (now[j]==0) continue;
                    for (k=0;k<m;k++)
                    {
                        if ((j & (1<<k))!=0) continue;//判断j的第k的位置为1
                        if (map[i+1][k]==0) continue;//在k的棚没有位置
                        p=(j | (1<<k));//j的第k的位置变1
                        now[p]+=now[j];
                    }
                    now[j]=0;
                }
            }
            ret=0;
            for (i=0;i<(1<<m);i++)
            {
                ret+=now[i];
            }
            printf("%d
    ",ret);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    JVM 的主要组成部分及其作用
    一天一个 Linux 命令(5):pwd命令
    算法-经典趣题-马踏棋盘(又称骑士周游)
    SAP HANA Schemas 和 HDI Containers
    如何手动下载并安装 Visual Studio Code 的 SAP Fiori tools
    一个最简单的 Github workflow 例子
    SAP UI5 初学者教程之七
    最近看的动漫和电影
    关于工作,干了这碗鸡汤
    啊啊啊啊啊啊
  • 原文地址:https://www.cnblogs.com/shuaihui520/p/9141216.html
Copyright © 2020-2023  润新知