ball
题目描述
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;
}

浙公网安备 33010602011771号