题目描述
LQX自从上次误导大家后一直觉得特别过意不去,这次他打算换一种玩法:他一共有n个白球(0)和m个黑球(1),他希望你帮他求出如果这些球按字典序排序(0排在1前面)的话,第k种排列方式是什么?如果不存在输出-1。
输入
输入若干组数据,每组数据包括一行三个数:n、m和k。
输出
按照题目要求输出每组样例的第k种排列。
样例输入
2 2 6
1 1 1
样例输出
1100
01
提示
对于100%的数据,1<=nm<=30,1<=k<=10^17,每组样例不超过10组数据。
题解:dp方程,dp[i][j]是i个白球,j个黑球的全排列个数,转移方程:dp[i][j]=dp[i][j-1]+dp[i-1][j];
如样例2 2 6,
全排列:
0 0 1 1
0 1 0 1
0 1 1 0
1 0 0 1
1 0 1 0
1 1 0 0
如果去掉第一位
去0:
0 1 1
1 0 1
1 1 0
相当于0,1,1的全排列
并且只有k>dp[i-1][j]时,cout<<1;
else cout<<0;
当然还有许多别的判断,详情请见代码:
#include<cstdio> #include<iostream> using namespace std; long long dp[35][35]; int main() { //freopen("ball.in","r",stdin); //freopen("ball.out","w",stdout); long long n,m; long long k; while(scanf("%lld",&n)!=-1 && scanf("%lld",&m)!=-1 && scanf("%lld",&k)!=-1) { for(int i=1;i<=30;i++) { dp[0][i]=1; dp[i][0]=1; } dp[0][0]=1; for(long long i=1;i<=30;i++) { for(long long j=1;j<=30;j++) { dp[i][j]=dp[i-1][j]+dp[i][j-1]; } } if(k>dp[n][m]) { cout<<-1<<endl; continue; } long long n2=n,m2=m; long long sum=n+m; while(sum) { if(k<=dp[n2-1][m2]&&n2>0) { n2--; cout<<0; } else { k-=dp[n2-1][m2]; m2--; cout<<1; } sum--; } cout<<endl; } return 0; }