一些杂题(排列组合

时间:2020-01-18
本文章向大家介绍一些杂题(排列组合,主要包括一些杂题(排列组合使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

排列组合小结

一.背景

今天做了几道题。有点小心得。

二.第二类stirling数

题面:

分析:用一下递推在加一个高精度cao过去

code:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int n,m,s[105][10005];
char ch[10005];
inline void out(int *a){
    int fl=0;
    for(int i=a[0];i>=1;--i){
        if(a[i])fl=1;
        if(fl)cout<<a[i];
    }
    cout<<endl;
}
inline void add(int *a,int *b,int *c){
    if(a[0]>b[0])add(b,a,c);
    else{
        memset(c,0,sizeof(int)*10005);
        int i;
        for(i=1;i<=a[0];++i){
            int res=a[i]+b[i]+c[i];
            if(res>=10)res-=10,c[i+1]++;
            c[i]=res;
        }i=a[0]+1;
        while(i<=b[0]){
            int res=b[i]+c[i];
            if(res>=10)res-=10,c[i+1]++;
            c[i]=res;
            ++i;
        }
        if(c[b[0]+1]!=0)c[0]=b[0]+1;
        else c[0]=b[0];
    }
}
inline void mul(int *a,int b,int *c){
    memset(c,0,sizeof(int)*10005);
    int i;
    for(i=1;i<=a[0];++i){
        int res=a[i]*b+c[i];
        if(res>=100)c[i+2]+=res/100,res%=100;
        if(res>=10)c[i+1]+=res/10,res%=10;
        c[i]=res;
    }
    if(c[a[0]+2]!=0)c[0]=a[0]+2;
    else if(c[a[0]+1]!=0)c[0]=a[0]+1;
    else c[0]=a[0];
}
int main(){
    cin>>n>>m;int u[10005];
    s[1][0]=1;s[1][1]=1;
    //add(s[1],s[1],u);out(u);
    for(int i=1;i<=n;++i){
        for(int j=i;j>=1;--j){
            mul(s[j],j,u);
            add(u,s[j-1],s[j]);//out(s[j]);
        }
    }
    out(s[m]);
}

三.核电站问题

相信大家都见过这个东西,虽然只是很简单的一个递推,但是它是可以作为一个反向解答的利器。核电站的核心思想是找出连续相同的项数不超过n的情况。如何引用下面会举例

下面挂一个核电站的核心code

f[0]=1;
for(int i=1;i<=n;++i){
        if(i<m)f[i]=f[i-1]*2;
        else if(i==m)f[i]=f[i-1]*2-1;
        else f[i]=2*f[i-1]-f[i-m-1];
    }

四.危险的组合

题面:有一些装有铀元素(用U表示)和铅元素(用L表示)的盒子,数量足够多,要求将N个盒子排成一行,但至少有M个U放在一起,有多少种方法?

思路:看起来,好像不太好做。但是我们可以从总数中剔除没有M个U放在一起的情况,此所谓正难反易。

挂一个code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll MAXN=10000000,mod=1000000007;
ll n,m,k,f[MAXN];
ll ans;
ll KSM(ll a,ll b,ll mod){
    ll p=1;
    while(b){
        if(b&1)p*=a;
        b>>=1;
        a=a*a;
    }
    return p;
}
int main(){
    cin>>n>>m;
    f[0]=1;
    for(int i=1;i<=n;++i){
        if(i<m)f[i]=f[i-1]*2;
        else if(i==m)f[i]=f[i-1]*2-1;
        else f[i]=2*f[i-1]-f[i-m-1];
    }
    cout<<KSM(2,n,mod)-f[n]<<endl;
}

$flag 上一页 下一页