• # 牛客挑战赛46_C题排列(前缀优化DP)


    牛客挑战赛46_C题排列(前缀优化DP)

    传送门

    题意:给定超级逆序对为k,求长度为n的排列的方案数;

    超级逆序对:满足 i<j 且 a[i]>a[j]+1 的二元组 (i,j);

    题解:若题目是逆序对个数为k,对于从1到n的每一个数,从小至大的插入数组,都有(0,i-1)的安排方案,枚举每一个数,记忆化搜索一下即可,现在多了一个超级逆序对,即每个数最多贡献i-2的超级逆序对的个数,并且会因为不同的i-1的位置影响不同的转移。所以我们可以给dp加一维i-1的位置信息,并加一层循环即可。空间是n3,时间是n4。爆空间,且超时。空间考虑滚动数组优化,并且我们容易发现转移具有单调性,所以利用预处理前缀和优化dp,达到n2空间,n3时间。

    #include<iostream>
    #include<cstring>
    using namespace std;
    #define ll long long
    const ll mod=998244353;
    ll n,k,lin[507][507],dp[507][507],pre[507][507];
    ll pow(ll x,ll n,ll mod){
        ll res=1;
    	while(n>0){
    	   if(n%2==1){
    	   	 res=res*x;
    	   	 res=res%mod;
    	   }
    	   x=x*x;
    	   x=x%mod;
    	   n>>=1;
    	}
    	return res;
    }
    ll inv(ll x){
    	return pow(x,mod-2,mod);
    }
    int main(){
    	cin>>n>>k;
    	lin[0][1]=1;
    	for(int i=2;i<=n;i++){
    		for(int j=0;j<=k;j++){
    			for(int c=1;c<i;c++){
    				pre[j][c]=(pre[j][c-1]+lin[j][c])%mod;
    			}
    		}
    		memset(dp,0,sizeof(dp));
    		for(int j=0;j<=k;j++){
    			for(int d=1;d<=i;d++){
    				dp[j][d]=(dp[j][d]+pre[j-i+d][d-1])%mod;
    				dp[j][d]=(dp[j][d]+(pre[j-i+d+1][i-1]-pre[j-i+d+1][d-1]+mod)%mod)%mod;
    			}
    		}
    		for(int j=0;j<=k;j++){
    			for(int d=1;d<=i;d++){
    				lin[j][d]=dp[j][d];
    			}
    		}
    	}
    	ll ans=0;
    	for(int i=1;i<=n;i++){
    		ans+=lin[k][i];
    		ans%=mod;
    	}
    	printf("%lld
    ",inv(ans));
    }
    
  • 相关阅读:
    Java 正则表达式的总结和一些小例子
    jquery用div模拟一个下拉列表框
    jquery点击div以外的区域触发事件
    Jackson 框架,轻易转换JSON
    Java Json API:Gson使用简单入门
    linux必学
    Python2 long() 函数
    Python int() 函数
    PyCharm快捷键大全
    PyCharm常用设置
  • 原文地址:https://www.cnblogs.com/whitelily/p/14212754.html
Copyright © 2020-2023  润新知