解题报告 之 SOJ1942 Foto
Description
The election campaign just started, so PSOS decided to make some propagation. One of the representatives came with a great idea - he proposes to make an photography of their Parliament Club. Unfortunatelly, even after many briefings, the representatives are still not able to agree upon an ordering of people in the photography. Moreover, there are a lot of representatives and it is not possible to have all of them in a single picture. The situation became critical. In the end, the representatives decided they will make one photo of every possible combination of people and their ordering. Different photographs will be used for a large number of billboards PSOS plan to use. To make things more clear, every person gets a Unique Identification Number (UIN). Every picture can be then described as the succession of several UINs x1, x2, ... xk, in whichxi is UIN of the i-th person in the picture x. Now we can sort all the possible photographs (combinations) to a single succession. The ordering of combinations of the same length (photographs with the same number of people in it) is defined as follows: the combination p is greater than the combination q if there exists any i such as that pj = qj for every j < i, and pi > qi. Your goal is to find the right place for a given picture among all possible photographs.
Input Specification
At the first line there is a positive integer N stating the number of assignments to follow. Each assignment consists of exactly two lines. At the first line of each assignment, there are two integers n and k, 1 <= k <= n <= 12 stating the total number of representatives (n) and the number of them which can fit into a single picture (k). At the second line of the assignment, there is exactly k positive numbers x1, x2, ... xk, each of them 1 <= xi <= n. No number can appear more than once on this line.
Output Specification
For each assignment, output the text "Variace cislo I ma poradove cislo J." (Combination #I is J-th in sequence). Fill the number of assignment instead of I (starting with one), and the number of the given photograph among all possible combinations after ordering, instead of J (also starting with one).
Sample Input
4 1 1 1 5 1 4 3 3 1 2 3 5 3 5 3 1
Output for Sample Input
Variace cislo 1 ma poradove cislo 1. Variace cislo 2 ma poradove cislo 4. Variace cislo 3 ma poradove cislo 1. Variace cislo 4 ma poradove cislo 55.
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
int greaterb4[15];
int num[15];
long long A( int a, int b )
{
long long res = 1;
for(int i = a; i > a-b; i--)
{
res *= i;
}
return res;
}
int main()
{
int kase;
cin >> kase;
int n, k;
for(int step = 1; step <= kase; step++)
{
memset( greaterb4, 0, sizeof greaterb4 );
cin >> n >> k;
for(int i = 1; i <= k; i++)
{
cin >> num[i];
for(int j = 1; j < i; j++)
{
if(num[j]>num[i]) greaterb4[i]++; //统计前面有几个更大的数
}
}//输入
long long ans = 0;
for(int i = 1; i <= k; i++)
{
long long tem = num[i]-(i-greaterb4[i]); //C(num,1) 其中num表示比这个数小且前面还没用过的数有多少个
tem *= A( n - i, k - i ); //剩下的数全排列
ans += tem;
}
printf( "Variace cislo %d ma poradove cislo %lld.\n", step, ans + 1 );
}
return 0;
}
题解到此结束。另外既然做到了就再顺便存一个超级叼的排列组合数模板。感觉可以O(n)时间预处理再在O(1)时间求出排列组合数。
#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
const int MAXN = 1e6;
double f[MAXN];
void fac()
{
f[0] = 0;
for(int i = 1; i < MAXN; i++)
{
f[i] = f[i - 1] + log( i*1.0 ) ;
}
}
double getA( int n, int m ) //计算A(n,m) 的值,n为右下角的数,m为右上角的数
{
return f[n] - f[n - m];
}
double getC( int n, int m )//计算C(n,m) 的值,n为右下角的数,m为右上角的数
{
return f[n] - f[m] - f[n - m];
}
int main()
{
fac();
int n, m;
while(cin >> n >> m)
{
printf( "A(%d,%d) = %lf\n", n, m, exp( getA( n, m ) ) );
printf( "C(%d,%d) = %lf\n", n, m, exp( getC( n, m ) ) );
}
return 0;
}
嗯,存个模板,暂时这个样吧!~~