靖爷的仙仙题,其实并不难,可是想了挺久,码了挺久,调了挺久,本人菜鸡了挺久,还是不够专注
就是问n的排列中,最长上升子序列长度为k的方案数,同时有一些约束
不难想到把求lis的单调栈压下来,但是还要压一个这个数字用了没有,状态数就是2^2n的了。感觉这个做法不对然后就想歪了
其实可以把这个东西压成三进制的,0不存在,1存在且在单调栈,2存在且已出单调栈,注意1,2不能调换,不然枚举顺序就出问题了
详情见代码。卡常没卡过
#include#include #include #include #include #include using namespace std;const int _=1e2;const int maxn=15+2;const int fbin=(1<<15)+_;const int tbin=14348907+_;int n,li;int m,num[maxn],rk[maxn],sf[fbin];void getsf(){ for(int i=1;i<=m;i++)rk[num[i]]=i; for(int zt=0;zt =1;i--) if(zt&(1< >1]+(zt&1); }}int mi[maxn],f[tbin];//0不存在,1存在且在单调栈,2存在且已出单调栈void divi(int zt,int &xx,int &yy)//该三进制是由(这个数是否存在)(这个数是否在单调栈里)两个二进制压缩而成的{ xx=0,yy=0; for(int i=1;i<=n;i++) { int d=zt/mi[i-1]%3; if(d>=1)xx|=(1<