DP(解码)
题意:给出一个串的长度n,串只有0,1组成,但是不能有两个相邻的1。按字典序给串排列,最先肯定是0000,接着是0001,依此类推。给一个数字m,输出在长度为n的情况下,第m个排列的串是什么,如果m大于总排列数,输出-1
这其实是一个解码的过程,必须用高位到低位解码(从左到右),因为这里要求字典序,字典序的比较水从左到右的
由于数据规模固定在串长度44以内,所以我们先dp出所有长度下可能的排列数,编码时也要用
每次编码按位编码,判断当前位为0还是为1,就是看填0或1可能产生多少排列数然后和m比较,这个看代码大概都能懂的
#include <cstdio> #include <cstring> #define N 55 long long dp[N][2]; int main() { memset(dp,0,sizeof(dp)); dp[1][1]=dp[1][0]=1; for(int i=2; i<44; i++) { dp[i][0]=dp[i-1][0]+dp[i-1][1]; dp[i][1]=dp[i-1][0]; } int n; long long m; int ans[N]; while(scanf("%d%lld",&n,&m)!=EOF) { if(m>dp[n][0]+dp[n][1]) { printf("-1\n"); continue; } while(n) { if(dp[n][0] >= m) //当前位填0已经满足 printf("0"); else //填0不满足 { m-=dp[n][0]; printf("1"); } n--; } printf("\n"); } return 0; }