第五关——数论:组合数学

20:44:00 你在台上唱着我的创作,布局谋篇像本悲情小说——许嵩《最佳歌手》

我的寒假,我美好的寒假啊啊啊

“其实我还蛮不想写你的,博客,可是没办法啊,谁叫我的寒假不要我了,我就只好要你了,博客”

目录

  • 鸽巢原理

  • 鸽巢原理推广

  • 杨辉三角和二项式系数

  • 容斥定理

  • 卡特兰数

  • 斯特林数

那接下来就要来看一下鸽巢原理(抽屉原理)

也不知道发现它的人是不是看着别人鸽子的窝盯半天才发现的,人家鸽子会不好意思的啦!

  • 定义:如果有n+1个鸽子要进n个鸽巢,则至少存在一个鸽巢种包含两个或更多的鸽子。
  • 例题:

    (2010问题求解3)记T为一队列,初始时为空,现有n个总和不超过32的正整数依次入队。如果无论这些数具体为何值,都能找到一种出队的方式,使得存在某个时刻队列T中的数之和恰好为9,那么n的最小值是_________。

    由题意可知bi取值范围为1-32,现将这32个数构造为集合{1,10},{2,11}, …, {8,17}, {18,27}, {19,28},…,{23,32} ,{24},{25},{26},这17个集合中的任一个集合不能包含两个或两个以上的 ,否则它们的差为9,故由鸽巢定理可得出,n的最小值为18.

  • 应用:

    在边长为1的正方形内任取5点,则其中至少有2点的距离不超过√2/2

  • 例题:

    吃糖果

    这道题是典型的鸽巢原理,可用鸽巢原理一种简单的推理方法隔板法进行分析,如果S<N-1.把S个糖果放到隔板之间,这N个隔板不够放.必然至少有两个隔板之间没有糖果,由于这两个隔板是同一种糖果,所以无解。反之则有解。

    注意开long long(尽管数据不大)

    #include <cstdio>
    #include<math.h>
    #include<algorithm>
     using namespace std;
    int main()
    {
        int i,j,n,sum,max_,t;
        scanf("%d",&t);
        {
            while(t--)
            {
                sum=max_=0;
                scanf("%d",&n);
                int *a=(int*)malloc(sizeof(int)*n);
                for(i=0;i<n;i++)
                {
                    scanf("%d",&a[i]);
                    max_=max(max_,a[i]);
                }
    
                for(i=0;i<n;i++)
                {
                    if(a[i]!=max_) sum+=a[i];
                    if(sum>=max_-1) break;
                }
    
                if(i==n) printf("No\n");
                else printf("Yes\n");
            }
        }
    }

鸽巢原理推广

  • 鸽巢原理的加强形式

定理: 令q1, q2, q3, ...., qn为正整数。如果将 q1, q2, q3, ...., qn - n + 1 个物体放到n个盒子中,则存在一个i,使得第i个盒子至少含有qi个物品 ;

证明: 假设将q1, q2, q3, ...., qn - n + 1个物品分别放到n个盒子里。如果每一个i (i = {1, 2, ..n}),第i个盒子中放少于qi 个物品,则所有盒子所放物品的总数不超过

    (q1 - 1) + (q2 - 1) + ... + (qn - 1) = q1 + q2 + ... + qn - n

显然,比所要放的总数少一个。因此可以确定,对某个i (i = {1, 2, .. n}),第i个盒子至少包含qi个物品。

  • Erdös-Szekeres定理

简单来说呢,就是在由n2+1n2+1个实数构成的序列中,必然含有长为n+1n+1的单调(增或减)子序列。

  • Ramsey定理

  1. 定义:对于一个给定的两个整m,n>=2,则一定存在一个最小整数r,使得用两种颜色(例如红蓝)无论给Kr的每条边如何染色,总能找到一个红色的Km或者蓝色的Kn。显然,当p>=r的时候,Kp也满足这个性质。
  2. 表示形式:r可以看做一个有关m,n的二元函数,即r(m,n)。r(3,3)=6.
  3. 性质:

    ①等价性 r(m,n)=r(n,m)

    ②r(2,n)=n k2较特殊 只有一条边 最小的kr为Kn

    ③r(m,2)=m

  4. 数表:

例题

Instability

问题很显然,6以及6以上的直接统计345的暴力统计就行了

就是说ans=3的个数+4的个数+5的个数+C(n,6)C(n,7)+…………+C(n,n)=2^n-C(n,0)-C(n,1)-C(n,2)-3不合法的个数-4不合法的个数-5不合法的个数。

#include<bits/stdc++.h>
using namespace std;
const int maxn=55;
const int mod=1000000007;
int T;
int a[maxn][maxn];
int cc=1;
int m,n;
void input(){
    scanf("%d%d",&n,&m);
    for (int i=1;i<=m;i++){
        int u,v;
        scanf("%d%d",&u,&v);
        a[u][v]=a[v][u]=1;
    }
}
bool ch(int x,int y,int z){
    int t=a[x][y]+a[x][z]+a[y][z];
    if (t==0||t==3)return true;
    return false;
}
bool h(int x,int y,int z,int w){
    return (ch(x,y,z)||ch(x,y,w)||ch(x,z,w)||ch(y,z,w));
}
bool e(int a,int b,int c,int d,int e){
    return (ch(a,b,c)||ch(a,b,d)||ch(a,b,e)||ch(a,c,d)||ch(a,c,e)||ch(a,d,e)||ch(b,c,d)||ch(b,c,e)||ch(b,d,e)||ch(c,d,e));
}
void solve(){
    long long ans=1;
    for (int i=1;i<=n;i++){
        ans = ans*2;
        ans%=mod;
    }
    ans-=n,ans--;
    ans-=n*(n-1)/2;
    ans+=mod;
    ans%=mod;
    for(int i=1;i<=n;i++)
    for(int j=i+1;j<=n;j++)
    for(int k=j+1;k<=n;k++)
    if(!ch(i,j,k))ans--;
    for(int i=1;i<=n;i++)
    for(int j=i+1;j<=n;j++)
    for(int k=j+1;k<=n;k++)
    for(int l=k+1;l<=n;l++)
    if(!h(i,j,k,l))ans--;
    for(int i=1;i<=n;i++)
    for(int j=i+1;j<=n;j++)
    for(int k=j+1;k<=n;k++)
    for(int l=k+1;l<=n;l++)
    for(int p=1+l;p<=n;p++)
    if(!e(i,j,k,l,p))ans--;
    ans+=mod;
    ans%=mod;
    printf("Case #%d: %lld\n",cc++,ans);
}
int main(){
    scanf("%d",&T);
    while (T--){
        memset(a,0,sizeof(a));
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++){
            int u,v;
            scanf("%d%d",&u,&v);
            a[u][v]=a[v][u]=1;
        }
        solve();
    }
    return 0;
}

Halloween treats

这道题就是鸽巢原理的运用。

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
const int mod=1e9+7;
typedef long long ll;
ll vis[maxn], a[maxn];
int main() {
    std::ios::sync_with_stdio(false);
    ll n, m;
    while(cin>>n>>m){
        if(!n&&!m){
            break;
        }
        ll sum=0,t;
        memset(vis,0,sizeof(vis) );
        for(ll i=1;i<=m;i++)
        cin>>a[i];
        for(ll i=1;i<=m;i++)
        {
            sum+=a[i];
            t=sum%n;
            if(t==0)
            {
                for(ll j=1;j<i;j++)
                cout<<j<<" ";
                cout<<i<<endl;
                break;
            }
            else if(vis[t])
            {
                for(ll j=vis[t]+1;j<i;j++)
                cout<<j<<" ";
                cout << i << endl;
                break;
            }
            vis[t] = i;
        }
    }
    return 0;
}

Friend-Graph

这道题用到的是Ramsey定理

#include<bits/stdc++.h>
using namespace std;
int T,n;
int main() {
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        int a[10][10]={0};
        for(int i=1; i<n; ++i)
        for(int j=i+1; j<=n; ++j)
        {
            int t;
            scanf("%d",&t);
            if(t&&n<6) a[i][j]=a[j][i]=1;
        }
        if(n>=6)
        {
            puts("Bad Team!");
            continue;
        }
        int f=0;
        for(int i=1;i<=n;++i)
        for(int j=i+1;j<=n;++j)
        for(int k=j+1;k<=n;++k)
        if(a[i][j]&&a[i][k]&&a[j][k])
        {
            f=1;
            break;
        }
        if(f) puts("Bad Team!");
        else puts("Great Team!");
    }
    return 0;
}

22:19:37 如果这失忆变成了洪水,也对,也对。——鬼卞《失眠症》

杨辉三角和二项式系数

杨辉三角小的时候都学过,那么杨辉三角有些什么规律呢,大家也都知道,那么求杨辉三角除了递推打表还有下面这种方法:

每一行从上一行推导而来。如果编程求杨辉三角第n行的数字,可以模拟这个推导过程,逐级递

推,复杂度是O(n2)。不过,若改用数学公式计算,则可以直接得到结果,比用递推快多了

,这个公式就是(1+x)n。

观察(1+x)n的展开:

(1+x)0 = 1

(1+x)1 = 1+x

(1+x)2 = 1+2x+x2

(1+x)3 = 1+3x+3x2+x3

每一行展开的系数刚好对应杨辉三角每一行的数字。也就是说,杨辉三角可以用(1+x)n来定

义和计算。

二项式定理公式:(a+b)n=C0nan+C1nan1b+?+Cknankbk+?+Cnnbn(n∈N∗)

二项式定理通项:Tk+1=Cknankbk

原文地址:https://www.cnblogs.com/wybxz/p/12250531.html

时间: 2024-10-10 16:58:18

第五关——数论:组合数学的相关文章

Codeforces 223APartial Sums 数论+组合数学

题意很简单,求不是那么好求的,k很大 要操作很多次,所以不可能直接来的,印象中解决操作比较多无非线段树 循环节 矩阵 组合数等等吧,这道题目 也就只能多画画什么 的了 就以第一个案例为主吧 , 3 1 2 3 k我们依据画的次数来自己定好了 下面的每个数表示这个位置的 数由最初的 数组num[]中多少个数加起来得到的 当k为0的时候呢,就是 1 1 1 k为1的时候呢 1 2 3 k为2的时候呢 1 3 6 那么k为3的时候 1 4 10 这里看一下 从数组下标0开始,那么其实就是 C(i +

【codecombat】 试玩全攻略 第十五关 名字大师

第十五关 名字大师 大眼一看,这一关跟上一关并没有什么不同,只是怪物有了名字,敌人1.敌人2.敌人3.好吧 要是怪物会说话,肯定会抗议的吧,我们兽人也是有尊严的! 代码如下: 1 # 你的英雄不知道这些敌人的名字! 2 # 这眼镜给了你寻找最近敌人的能力. 3 4 enemy1 = hero.findNearestEnemy() 5 hero.attack(enemy1) 6 hero.attack(enemy1) 7 enemy2 = hero.findNearestEnemy() 8 her

团队项目:第五关攻略

第五关 第五关过关方法不唯一,以下给出一种方案. 利用开关门消去中间平台,即可抵达终点.

webug第五关:一个优点小小的特殊的注入

第五关:一个优点小小的特殊的注入 既然是头部注入,首先想到xff注入 出现数据库报错,而且他是直接将xff后的内容带入数据库查询

webug第十五关:什么?图片上传不了?

第十五关:什么?图片上传不了? 直接上传php一句话失败,将content type改为图片 成功

sqli-labs-master第五关Less-5 Double Query- Single:方式一

由于第三四关和第一第二关大致相同,我就不写了. 接下来来写第五关的第一种方式. 1,目标网站: http://127.0.0.1/sqli-labs-master/Less-5/?id=1 当传递的ID为1的时候提示"you are in" 2,查找注入点: http://127.0.0.1/sqli-labs-master/Less-5/?id=1' 返回错误 当输入上面的url的时候就报错了.我们可以从箭头处看到报错的原因. 说明把"1'"带入数据库查询了,所以

XSS闯关之第五关

开启第五关查看源码,进行分析当我第一眼看到这个代码的时候,就想着用上一关的payload,只需要将其大写就可.但是结局往往就是残酷.激动之下忽略了另一个函数strtolower(),此函数,将所有的字母全部转化为小写.所以造成我的大写payload没有什么用.将字母转换为小写后复制给变量str,然后此变量经过str_spelace()函数将其中的<script转换为<sc_ript,将转换后的字符串赋值给变量str2.这样我们的<script>标签就不能使用Str2经过str_sp

CodeForces 396A 数论 组合数学

题目:http://codeforces.com/contest/396/problem/A 好久没做数论的东西了,一个获取素数的预处理跟素因子分解写错了,哭瞎了,呵呵, 首先ai最大值为10^9,n为500,最坏的情况 m最大值为500个10^9相乘,肯定不能获取m了,首选每一个ai肯定是m的一个因子,然后能分解就把ai给分解素因子,这样全部的ai都分解了  就能得到m的 所有素因子 以及 所有素因子的个数,题目求的 是n个因子的 不同序列的个数,所以每次 只能选出n个因子,这n个因子由素因子

pythonchallenge 第五关

因为前几关代码已近删了,所以从这一关开始. 思路我都是在网上找的,比如 http://blog.csdn.net/zlchina1989/article/details/6864562. 所以我在这边只贴上代码: import urllib.request import re import pickle url = "http://www.pythonchallenge.com/pc/def/banner.p" res = urllib.request.urlopen(url) dat