UVA11806【拉拉队】Cheerleaders-------2015年1月24日

本文探讨了在一个M行N列的广场上安排K个拉拉队员的问题,并提出了使用容斥原理解决该问题的方法。文章详细介绍了算法思路,包括如何通过预处理组合数避免重复计算,以及如何利用二进制状态表示进行容斥计算。

1.题意描述

本题大致意思是讲:给定一个广场,把它分为M行N列的正方形小框。现在给定有K个拉拉队员,每一个拉拉队员需要站在小框内进行表演。但是表演过程中有如下要求:

(1)每一个小框只能站立一个拉拉队员;

(2)广场的第一行,最后一行,第一列,最后一列都至少站有一个拉拉队员;

(3)站在广场的四个角落的拉拉队员可以认为是同时占据了一行和一列。

2.思路分析:

本题如果直接枚举的话难度很大并且会无从下手。那么我们是否可以采取逆向思考的方法来解决问题呢?我们可以用总的情况把不符合要求的减掉就行了。

首先我们如果不考虑任何约束条件,我们可以得出如下结论:

                                                                     

下载我们假定第一行不站拉拉队员的所有的站立方法有A种。最后一行不站拉拉队员的所有的方法有B种。第一列不站拉拉队员的所有的站立方法有C种。最后一列不站拉拉队员的站立方法有D种。

下面我们可以得出最后结果:

                              

下面问题来了我们如何利用代码实现容斥原理呢?我们可以借用离散数学的最大项和最小项知识结合与运算来判断每一项的特征。比如说,含A的和1进行与运算。含B的与2进行与运算。含C的和4进行与运算。含D的和8进行与运算。

然后对于每一种状态,我们利用数字0-15来代替。

在进行这些工作之前,我们还要进行基础性工作,数据初始化和打表。

对于如何打表,我们可以采取组合数公式的递推式进行。打表过程中一定要注意边界问题的处理,要不极容易出错。

3.AC代码

    #include<iostream>
    #include<cstdio>
    #include<algorithm>//注意头文件的使用
    #include<string.h>
    using namespace std;
    #define maxn 500+5
    const int mod=1000007;
    int c[maxn][maxn];//数组c[i][j]表示在i个可用的点中抽取j个点的情况总数

    void process()//函数预处理过程相当于打表这样节省时间
    {
        memset(c,0,sizeof(c));
        c[0][0]=1;
        for(int i=1;i<maxn;i++)
        {
            c[i][0]=c[i][i]=1;//初始化边界
            for(int j=1;j<i;j++)//注意是j<i不能超多这是由于C[i][j]的定义得来的
                c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;//组合数公式的递推式
        }
    }
    int main()
    {
        process();
        int T;
        cin>>T;
        for(int Case=1;Case<=T;Case++)
        {
            int sum=0;
            int n,m,k;
            cin>>n>>m>>k;
            for(int s=0;s<16;s++)//处理容斥原理的方式,与运算
            {
                //当s=0时就相当于我们在分析过程中的sum1
                int r=n,c1=m;int b=0;//注意理解其中的b
                if(s&1) {r--;b++;}
                if(s&2){r--;b++;}
                if(s&4){c1--;b++;}
                if(s&8){c1--;b++;}
                if(b&1){sum=(sum+mod-c[r*c1][k])%mod;}//说明含有奇数个项如ABD,A等
                else sum=(sum+c[r*c1][k])%mod;//说明含有偶数个项如ABCD,AB等
            }
            printf("Case %d: ",Case);
            printf("%d\n",sum);
        }
        return 0;
    }

4.总结

本题要注意正难则反策略,容斥原理,以及代码实现容斥原理的应用。

转载于:https://www.cnblogs.com/khbcsu/p/4245943.html

(1)普通用户端(全平台) 音乐播放核心体验: 个性化首页:基于 “听歌历史 + 收藏偏好” 展示 “推荐歌单(每 30 首)、新歌速递、相似曲风推荐”,支持按 “场景(通勤 / 学习 / 运动)” 切换推荐维度。 播放页功能:支持 “无损音质切换、倍速播放(0.5x-2.0x)、定时关闭、歌词逐句滚动”,提供 “沉浸式全屏模式”(隐藏冗余控件,突出歌词与专辑封面)。 多端同步:自动同步 “播放进度、收藏列表、歌单” 至所有登录设备(如手机暂停后,电脑端打开可继续播放)。 音乐发现与管理: 智能搜索:支持 “歌曲名 / 歌手 / 歌词片段” 搜索,提供 “模糊匹配(如输入‘晴天’联想‘周杰伦 - 晴天’)、热门搜索词推荐”,结果按 “热度 / 匹配度” 排序。 歌单管理:创建 “公开 / 私有 / 加密” 歌单,支持 “批量添加歌曲、拖拽排序、一键分享到社交平台”,系统自动生成 “歌单封面(基于歌曲风格配色)”。 音乐分类浏览:按 “曲风(流行 / 摇滚 / 古典)、语言(国语 / 英语 / 语)、代(80 后经典 / 2023 新歌)” 分层浏览,每个分类页展示 “TOP50 榜单”。 社交互动功能: 动态广场:查看 “关注的用户 / 音乐人发布的动态(如‘分享新歌感受’)、好友正在听的歌曲”,支持 “点赞 / 评论 / 转发”,可直接点击动态中的歌曲播放。 听歌排行:个人页展示 “本周听歌 TOP10、累计听歌时长”,平台定期生成 “全球 / 好友榜”(如 “好友中你本周听歌时长排名第 3”)。 音乐圈:加入 “特定曲风圈子(如‘古典音乐爱好者’)”,参与 “话题讨论(如‘你心中最经典的钢琴曲’)、线上歌单共创”。 (2)音乐人端(创作者中心) 作品管理: 音乐上传:支持 “无损音频(FLAC/WAV)+ 歌词文件(LRC)+ 专辑封面” 上传,填写 “歌曲信息
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值