首页 > 其他分享 >luogu P8859 冒泡排序

luogu P8859 冒泡排序

时间:2022-11-23 10:02:01浏览次数:80  
标签:P8859 luogu ll db 冒泡排序 long using dp define

题面传送门

首先\(type=1\)的情况是平凡的,设可以发现一个数不需要被操作当且仅当这个数前面的数都小于这个数。可以设计出这样的dp:设\(f_{i,j}\)表示到了第\(i\)个数,前面有\(j\)个数需要操作的方案数,则有两种平凡。

然后\(type=2\)的情况下我就陷入误区了,以为一定要将\(1\)单独处理,先把\(1\)的位置定下来断环为链。但是实际上这样使得这个结构变得不优美。正确的姿势是钦定一条边不能过然后断环为链,然后当成排列做。

但是还是不是很好做。实际上不需要操作的就是前缀最大值,这个在笛卡尔树上表现出来就是一条从根节点开始的左链,然后现在能把左边的一些节点扔到右边去,问所有情况下的最大值。这实际上就是每个点走到根路径上左边的最大值。可以对树计数做到\(O(n^4)\),前缀和变成\(O(n^3)\)。

#include<bits/stdc++.h>
#define Gc() getchar() 
#define Me(x,y) memset(x,y,sizeof(x))
#define Mc(x,y) memcpy(x,y,sizeof(x))
#define d(x,y) ((m)*(x-1)+(y))
#define R(n) (rnd()%(n))
#define Pc(x) putchar(x)
#define LB lower_bound
#define UB upper_bound
#define PB push_back
using ll=long long;using db=double;using lb=long db;using ui=unsigned;using ull=unsigned ll;
using namespace std;const int N=5e2+5,M=10+5,K=1e5+5,mod=1e9+7,Mod=mod-1,INF=2e9+7;const db eps=1e-5;mt19937 rnd(263082);
int n,k,op;
namespace Solve1{
	ll dp[N][N];void Solve(){
		int i,j;dp[0][0]=1;for(i=1;i<=n;i++){
			for(j=0;j<=i;j++)dp[i][j]=dp[i-1][j],j&&(dp[i][j]=(dp[i][j]+dp[i-1][j-1]*(i-1))%mod);
		}printf("%lld\n",dp[n][k]);
	}
}
namespace Solve2{
	ll dp[N][N],Q[N][N],C[N][N];void Solve(){
		int i,j,x,y;for(i=0;i<=n;i++) for(C[i][0]=j=1;j<=i;j++) C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;
		dp[0][0]=1;for(i=0;i<=n;i++) Q[0][i]=1;for(i=1;i<n;i++){
			for(j=0;j<i;j++){
				for(x=0;x<=j;x++) dp[i][x+1]+=dp[j][x]*Q[i-j-1][x]%mod*C[i-1][j]%mod;
				for(y=1;y<=i-j-1;y++) dp[i][y]+=Q[j][y-1]*dp[i-j-1][y]%mod*C[i-1][j]%mod;
			}
			for(j=1;j<=n;j++) dp[i][j]%=mod,Q[i][j]=(Q[i][j-1]+dp[i][j])%mod;
		} printf("%lld\n",dp[n-1][n-k-1]);
	}
}
int main(){
	freopen("1.in","r",stdin);
	scanf("%d%d%d",&n,&k,&op);if(op==1) Solve1::Solve();else Solve2::Solve();
}

标签:P8859,luogu,ll,db,冒泡排序,long,using,dp,define
From: https://www.cnblogs.com/275307894a/p/16917329.html

相关文章

  • Luogu P1306 斐波那契数列公约数
    斐波那契公约数题目描述对于Fibonacci数列:\[f_i=\begin{cases}[i=1]&i\leq1\\f_{i-1}+f_{i-2}&i\gt1\end{cases}\]请求出......
  • Luogu2046 海拔 - 网络流 - 最短路 -
    题目链接:https://www.luogu.com.cn/problem/P2046首先观察可以发现最优解一定是左上部分是全0,右下是全1这样的形式然后题目就相当于让我们求一个\((1,1)\rightarrow(n......
  • Luogu7093
    题意:给你一个双端队列,同时有一个长度为\(n\)的序列\(a\),满足序列中的元素均为\(2\)的非负整数幂。从前到后遍历这个序列,对于一个\(a_i\)你可以将它放入双端队列的......
  • C语言之冒泡排序
    #include<stdio.h>voidbubble_sort(intarr[],intsz){//确定冒泡排序的趟数inti=0;for(i=0;i<sz-1;i++){intflag=1;//假设这一趟冒泡排序已经有......
  • 数组部分基础&冒泡排序
    数组基础知识 1.数组的创建格式:变量(数组)类型变量(数组)名=变量(数组)值int[]nums;//声明一个数组nums=newint[10];//创建一个数组int[]nums=new......
  • 冒泡排序法
    voidBubbleSort(ints[],intn){//函数参数:数组与数组大小 inti,j,temp; for(i=0;i<n-1;i++)//从0开始进行n-1轮排序 {......
  • 随机数的生成+冒泡排序法
     大家好呀,今天要给大家带来的是随机数的生成和冒泡排序法结合的知识点。首先随机数的生成,随机数顾名思义就是由电脑随机产生的数字,如果每次都由人工输入数字的话会很麻烦,......
  • Luogu P3286 [SCOI2014]方伯伯的商场之旅
    题意方伯伯有一天去参加一个商场举办的游戏。商场派了一些工作人员排成一行。每个人面前有几堆石子。说来也巧,位置在\(i\)的人面前的第\(j\)堆的石子的数量,刚好是\(......
  • 算法-2 选择排序、冒泡排序、插入排序
    一选择排序选择排序的时间复杂度O(n2),额外空间复杂度O(1)publicstaticvoidSelectionSort(int[]arr){if(arr==null||arr.Length<2){ret......
  • 冒泡排序
    //冒泡排序packagecom.ShiXun_JiChu;importjava.util.Arrays;publicclassday20221119_05{publicstaticvoidmain(String[]args){int[]arr={10,5,2,1......