最长不下降子序列 输出方案数
2010-11-12 14:22
344 查看
对于最长不下降子序列的求解,朴素的解法是N^2的,也可以用单调队列优化,从而降时间复杂度为Nlog(n).
涉及到方案数的输出时,只需要降长度为1的最长XX子序列的方案数赋成1,其他的长度的方案数均由前一个长度的方案推出.
如下图所示:
首先用朴素的最长非降子序列的方法求出每一个在最优序列中的位置:
建立如下的表
值的大小: 68 69 54 64 68 64 70 67 78 62 98 87
在序列中的位置 3 4 1 2 3 2 3 2 2 2 1 1(这里的在序列中的位置即是指以这个数为起点的最长XX子序列的长度)
下面是对方案的判重,这列我们借助一个一维的辅助数组来帮助判重.
foreverzsz原创,转载请注明出处。
本文出处:/article/5566612.html
涉及到方案数的输出时,只需要降长度为1的最长XX子序列的方案数赋成1,其他的长度的方案数均由前一个长度的方案推出.
如下图所示:
首先用朴素的最长非降子序列的方法求出每一个在最优序列中的位置:
建立如下的表
值的大小: 68 69 54 64 68 64 70 67 78 62 98 87
在序列中的位置 3 4 1 2 3 2 3 2 2 2 1 1(这里的在序列中的位置即是指以这个数为起点的最长XX子序列的长度)
下面是对方案的判重,这列我们借助一个一维的辅助数组来帮助判重.
.z[0]=1]下面给出输出方案数的程序: 题目是USACO的 Section 4.3 .1Buy Low, Buy Lower (代码比较冗余,可去NOCOW上看较为标准的代码) #include <cstdlib> #include <cstdio> #include <cstring> struct { int z[15]; }time[10000]; int panchong[10000]; int a[10000]; int f[10000]; void add(int a[15],int b[15],int c[15]) { int d[15]; memset(d,0,sizeof(d)); int len; if (a[0]>b[0]) len=a[0];else len=b[0]; for (int i=1;i<=len;i++) { d[i]+=(a[i]+b[i]); d[i+1]+=(d[i]/100000000); d[i]=d[i]%100000000; } d[0]=len+2; while (d[d[0]]==0&&d[0]>0) d[0]--; while (d[d[0]]>=100000000) { d[d[0]+1]=d[d[0]]/100000000; d[0]++;} memset(c,0,sizeof(c)); for (int i=0;i<=d[0];i++) c[i]=d[i]; } void print(int a[15]) { printf("%d",a[a[0]]); for (int i=a[0]-1;i>0;i--) { if (a[i]/10000000==0) printf("0"); if (a[i]/1000000==0) printf("0"); if (a[i]/100000==0) printf("0"); if (a[i]/10000==0) printf("0"); if (a[i]/1000==0) printf("0"); if (a[i]/100==0) printf("0"); if (a[i]/10==0) printf("0"); printf("%d",a[i]); } printf("\n"); } int main() { freopen("plane.in","r",stdin); freopen("plane.out","w",stdout); int n; scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d",&a[i]); a[n+1]=-1000000; f[n+1]=0; for (int i=n;i>0;i--) for (int j=i+1;j<=n+1;j++) { if (a[i]>a[j]&&f[i]<f[j]+1) f[i]=f[j]+1; } memset(time,0,sizeof(time)); time[n+1].z[0]=1; time[n+1].z[1]=1; for (int i=n;i>0;i--) { panchong[0]=0; for (int j=i+1;j<=n+1;j++) { bool boo=false; if (f[j]==f[i]-1&&a[j]<a[i]) { for (int k=1;k<=panchong[0];k++) if (panchong[k]==a[j]) {boo=true;break;} if (boo==false){panchong[++panchong[0]]=a[j];add(time[i].z,time[j].z,time[i].z);} } } } int maxx=0; for (int i=1;i<=n;i++) if (f[i]>maxx) {maxx=f[i];}; panchong[0]=0; int biao[15]; memset(biao,0,sizeof(biao)); for (int i=1;i<=n;i++) if (f[i]==maxx) { bool boo=false; for (int k=1;k<=panchong[0];k++) if (a[i]==panchong[k]) {boo=true;break;} if (boo==false) {panchong[++panchong[0]]=a[i];add(biao,time[i].z,biao);} } printf("%d ",maxx); print(biao); return 0; }
foreverzsz原创,转载请注明出处。
本文出处:/article/5566612.html
相关文章推荐
- 洛谷Oj-低价购买-最长下降子序列 +最佳方案数统计
- wust oj 1867 (输出最长不下降子序列)【最长序列输出类模板】
- 最长下降子序列 + 最长的方案数
- POJ-1952 最长下降子序列 + 方案数
- 最长不下降子序列的O(n*logn)算法
- 最长不下降子序列(二)
- joj 2529 Chorus 动态规划 最长上升子序列和最长下降子序列
- 【HDU6197 2017 ACM ICPC Asia Regional Shenyang Online D】【LIS 最长不下降序列】array array array 数列删除恰好K个数,使得恰好
- 关于DP中的最长不下降序列问题分析
- [HNOI2004]打鼹鼠&Codevs_P1256 打鼹鼠(DP+最长不下降子序列变形)
- BZOJ 1852 [MexicoOI06]最长不下降序列(贪心+DP+线段树+离散化)
- Codeforces 10D LCIS 求最长公共上升子序列及输出这个子序列 dp
- Java实现求最长增长子序列长度,并输出该子序列值
- 最长上升子序列 Longest Increasing Subsequence 输出其中一个序列 O(n^2) O(nlogn)
- hdu 1160 FatMouse's Speed(最长不下降子序列+输出路径)
- 【最长上升子序列 && 输出路径】HDU - 1160 FatMouse's Speed
- hdu 4604 Deque(最长上升与下降子序列-能够重复)
- 最长不下降子序列(n*logn)
- [dp]poj1088_滑雪 二维形式的最长下降子序列
- 最长不下降子序列的o(nlogn)算法