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;
}
原文地址:https://www.cnblogs.com/chen-1/p/9480321.html