zoukankan      html  css  js  c++  java
  • 排列最小值

    也许更好的阅读体验

    (mathcal{Description})
    problem
    多组询问
    (1 leq n,Qleq 10^5)

    (mathcal{Solution})

    (50)分解法

    考虑(DP),感觉上直接算答案不好算,所以考虑算长度为(n)的所有排列改变的次数的排列的个数算出来
    之后再把个数乘以次数的平方即可
    (f_{i,j})表示长度为(i)的排列的改变次数(j)排列个数
    考虑把最大的(i)插入到长度为(i-1)的改变次数为(j)的排列中,则有(i)个空可以插,其中最前面的空插进去会使改变次数加一,所以有(i-1)个空使改变次数不变
    考虑插在最前面则原改变次数应为(j-1)
    所以(f_{i,j}=f_{i- 1,j}*(i-1)+f_{i-1,j-1})
    其实就是第一类斯特林数的递推公式
    提前预处理一下即可做到 (n^{2})

    (100)分解法

    仍然是(DP),原来的是把问题拆开,好做但是不能直接算
    不妨大胆一点,设(f_i)表示长度为(i)答案
    仍然考虑从(i-1)转移过来
    还是上面那句
    考虑把最大的(i)插入到长度为(i-1)的改变次数为(j)的排列中,则有(i)个空可以插,其中最前面的空插进去会使改变次数加一,所以有(i-1)个空使改变次数不变
    (f_i=f_{i-1}*(i-1)+插到最前面的贡献)
    考虑插在最前面,原本的改变次数为(x)的都变为(x+1)
    也就是(x^2 -> (x+1)^2=x^2+2x+1)
    我们设(g_i)表示原本算贡献时是按照(x)来算的长度为(i)的答案
    对于那个(1),因为插在最前面后面的(i-1)个数共有((i-1)!)种组合
    所以(f_i=f_{i-1}*(i-1)+f_{i-1}+2g_{i-1}+(i-1)!=f_{i-1}*i+f_{i-1}+(i-1)!)
    (g_i)同样这么推
    (g_i=g_{i-1}*i+(i-1)!)

    (mathcal{Code})

    /*******************************
    Author:Morning_Glory
    LANG:C++
    Created Time:2019年09月28日 星期六 09时34分38秒
    *******************************/
    #include <cstdio>
    #include <fstream>
    using namespace std;
    const int maxn = 100005;
    const int mod = 998244353;
    //{{{cin
    struct IO{
    	template<typename T>
    	IO & operator>>(T&res){
    		res=0;
    		bool flag=false;
    		char ch;
    		while((ch=getchar())>'9'||ch<'0')	flag|=ch=='-';
    		while(ch>='0'&&ch<='9')	res=(res<<1)+(res<<3)+(ch^'0'),ch=getchar();
    		if (flag)	res=~res+1;
    		return *this;
    	}
    }cin;
    //}}}
    int T,n;
    int f[maxn],g[maxn],fac[maxn];
    int main()
    {
    	fac[0]=1;
    	for (int i=1;i<=100000;++i){
    		fac[i]=1ll*fac[i-1]*i%mod;
    		f[i]=((1ll*f[i-1]*i%mod+2ll*g[i-1]%mod)%mod+fac[i-1])%mod;
    		g[i]=(1ll*g[i-1]*i%mod+fac[i-1])%mod;
    	}
    	cin>>T;
    	while (T--){
    		cin>>n;
    		printf("%d
    ",f[n]);
    	}
    	return 0;
    }
    
    

    如有哪里讲得不是很明白或是有错误,欢迎指正
    如您喜欢的话不妨点个赞收藏一下吧

  • 相关阅读:
    C#多线程参数传递
    Delphi单元测试工具Dunit介绍
    使用javascript生成文件
    Windows自动登录源码
    [Win32]一个调试器的实现
    用MASM写一个简单的实现递归操作的汇编程序,所谓递归,上课已经跟大家说清楚了,如果我们只考虑简单的只分一次的递
    C#多线程编程(4)多线程与UI操作
    在Delphi中实现类型安全的容器,Delphi泛型库DGL引介(提供源码下载) .
    delphi 中几种多线程操作方式
    C#实现WEB服务器
  • 原文地址:https://www.cnblogs.com/Morning-Glory/p/11604427.html
Copyright © 2011-2022 走看看