DP+树状数组优化-sort it-neu2016第一次月赛
来源:互联网 发布:网络时间参数计算例题 编辑:程序博客网 时间:2024/06/05 08:11
问题 F: Sort It
时间限制: 6 Sec 内存限制: 128 MB提交: 31 解决: 9
[提交][状态][讨论版]
题目描述
You are given a permutation of length n:p1,p2,...pn.Consider arrays of length n with possibly equal number from 1 to n.
If after rearrange elements of the array in the order of “all numbers equal to p1,all numbers equal to p2...all numbers equal to pn”,
the array become non-decreasing,then we call the array is sortable by p.
Calculate the total number of arrays that are sortable by p.
As the answer can be very large,output it after module 1e9+7.
输入
Several test cases.
The first line contains a single integer n(1<=n<=2000),the length of permutation.
The second line contains n distinct integers p1,p2,..pn(1<=pi<=n).
输出
Output a singe number -- the answer to the problem module 1e9+7.
样例输入
22 132 1 3
样例输出
215
提示
Anything about the Problems, Please Contact Admin:admin
All Copyright Reserved 2010-2015 NEU-ACM TEAM
GPL2.0 2003-2013 HUSTOJ Project TEAM
All Copyright Reserved 2010-2015 NEU-ACM TEAM
GPL2.0 2003-2013 HUSTOJ Project TEAM
题目大意:有点难懂。。大致就是给一个n,然后再给一个n个数的排列,问所有(1,...,1)到(n,....,n)的排列中如果通过一个操作,将所有的数按照先前给出的那个数列的顺序进行排列,会形成一个不下降序列,求这样的排列个数。
题目解法:读懂题意后,很容易想到求出所有不同长度的不下降序列的个数,然后分别对应乘上一个事先可以求出的x种数形成n的排列的个数,最后将所有结果相加就好。x种数形成n的排列的个数可以用递推求。递推式是f[i][j]=(f[i-1][j-1]*j%mod+f[i-1][j]*j%mod)%mod;初始f[0][0]=1;之后就是一个求不下降序列的长度问题,很容易想到一个n三次方的DP方法但是时间复杂度不够,我们需要通过树状数组优化到n方logn。具体优化是将三方算法中的求和公式dp[i][j]=∑dp[k][j-1]时,a[k]<a[i]时,实现对原数组进行排序,然后用树状数组直接求比他小的dp值。
具体代码:
<span style="font-style: normal;">#include<bits/stdc++.h>using namespace std;const long long mod=1e9+7;int n;long long dp[2222][2222]; //dp[i][j]表示以下表i结尾,长度为j的不下降子序列。其中i是新的i(排序后的)long long tree[2222][2222]; //树状数组维护当前的值struct NODE { long long num; int pos;}a[2222];int lowbit(int x) { return x&-x;}void add(int x,int l,int v) { // l 是指长度其实是个一维树状数组的叠加 for(int i=x;i<=n;i+=lowbit(i)) tree[i][l]=(tree[i][l]+v)%mod;}long long query(int x,int l) { long long sum=0; for(int i=x;i>0;i-=lowbit(i)) { sum=(sum+tree[i][l])%mod; } return sum;}bool cmp(NODE a,NODE b) { return a.num<b.num;}long long f[2222][2222];int main(){ f[0][0]=1; for(int j=1;j<=2000;j++) //初始x种元素组合成n个数的排列 for(int i=j;i<=2000;i++) { f[i][j]=(f[i-1][j-1]*j%mod+f[i-1][j]*j%mod)%mod; } while(scanf("%d",&n)!=EOF) { memset(dp,0,sizeof dp); memset(tree,0,sizeof tree); for(int i=1;i<=n;i++) { scanf("%lld",&a[i].num); //记录原先坐标 a[i].pos=i; } sort(a+1,a+n+1,cmp); for(int i=1;i<=n;i++) { for(int j=1;j<=i;j++) { if(j==1) dp[i][j]=1; else dp[i][j]=query(a[i].pos-1,j-1); //询问比他小的数所以pos-1,询问少一个数的所以j-1。 add(a[i].pos,j,dp[i][j]); //修改 } } long long ans=0; for(int i=1;i<=n;i++) for(int j=1;j<=i;j++) ans=(ans+dp[i][j]*f[n][j])%mod; printf("%lld\n",ans); } return 0;}</span>
0 0
- DP+树状数组优化-sort it-neu2016第一次月赛
- Sort It (树状数组+dp)
- hdu2689 Sort it (树状数组)
- hdu2689 Sort it (树状数组)
- HDU2689 Sort it【树状数组】【逆序数】
- HDU 2689 Sort it (树状数组)
- 杭电Sort it 2689树状数组
- HDU 2689 Sort it [树状数组]【数据结构】
- hdu 2689 Sort it(树状数组)
- HDU2689 Sort it (树状数组|水题)
- HDU 2689 Sort it 树状数组
- 【HDU4991】dp 树状数组优化
- hdu5542 树状数组优化dp
- BZOJ3594 树状数组优化DP
- 【树状数组+简单题】杭电 hdu 2689 Sort it
- nyoj- 117 求逆序数 && hdu-sort it----> 树状数组
- HDU2689 Sort it (树状数组求逆序数)
- HDU 2689 Sort it 求逆序数,树状数组实现
- ActionScript 3.0 学习(十五) 基于as的聊天程序,服务器端和客户端
- SpringMvc访问静态资源的几种方法
- 猜数字游戏
- 十六进制的字符串与二进制字符串相互转换
- 营业外收入预算
- DP+树状数组优化-sort it-neu2016第一次月赛
- pcie干货系列之-TLP’s size/TLP fail/4K boundary/requs
- 文件读写和输入输出重定向
- ReactiveCocoa简介6,添加附加操作(Adding side-effects)
- 初学者github会遇到的错误
- Android Animations动画使用详解
- spark_2:spark的基础
- linux下安装googletest
- android 机器耗电