zoukankan      html  css  js  c++  java
  • 一些杂题(排列组合

    排列组合小结

    一.背景

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

    二.第二类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;
    }
    
  • 相关阅读:
    C++课程学习笔记第六周:多态
    C++课程学习笔记第五周:继承
    C++课程学习笔记第四周:运算符的重载
    C++课程学习笔记第三周:类和对象提高
    C++课程学习笔记第一周:从C到C++
    C++课程学习笔记第二周:类和对象基础
    PyTorch的安装及学习资料
    PyTorch练手项目一:训练一个简单的线性回归
    PyTorch练手项目二:MNIST手写数字识别
    PyTorch练手项目四:孪生网络(Siamese Network)
  • 原文地址:https://www.cnblogs.com/clockwhite/p/12209619.html
Copyright © 2011-2022 走看看