Question link: http://acm.hdu.edu.cn/showproblem.php? PID = 1, 4996
Question: How many of the longest ascending subcolumns in the full arrangement of 1 to n are K?
Idea: for the current longest ascending subcolumn, we can record the last one worth the minimum value. Therefore, we use the 2 ^ n State to indicate which numbers are used in the current longest ascending subcolumn, And the Lexicographic Order is the smallest. After the first n-1 digits, we enumerate the numbers in the last position as each digit in [1, N] and set it to K. Then we only need to set the first [1, n-1] all the numbers in the series that are greater than or equal to K can be incremented by one.
int n,k;i64 f[22][22];i64 dp[1<<22],tmp[1<<22];int cal(int x){ int ans=0; int i; for(i=0;i<20;i++) if(x&(1<<i)) ans++; return ans;}void init(){ dp[1]=1; f[1][1]=1; int i,j; for(i=1;i<18;i++) { for(j=0;j<(1<<i);j++) tmp[j]=dp[j]; for(j=0;j<(1<<(i+1));j++) dp[j]=0; for(j=0;j<(1<<i);j++) if(tmp[j]) { int k; for(k=0;k<=i;k++) { int tot=0; int c[20]; int t; for(t=0;t<i;t++) if(j&(1<<t)) c[tot++]=t; for(t=0;t<tot;t++) if(c[t]>=k) c[t]++; c[tot++]=k; for(t=0;t<tot;t++) if(c[t]>k) { c[t]=k; break; } int st=0; for(t=0;t<tot;t++) st|=1<<c[t]; dp[st]+=tmp[j]; } } for(j=0;j<(1<<(i+1));j++) f[i+1][cal(j)]+=dp[j]; }}int main(){ init(); int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&k); printf("%I64d\n",f[n][k]); }}
HDU 4996 revenge of LIS (DP)