问题描述:
Description
Consider m natural numbers n1, n2, ..., nm with the property n1 >= n2 >= ... >= nm > 0.
We define a Young table as an arrangement in a table of n1 + n2 + ... + nm natural numbers (bigger than 0 and any two different), so that the ith line has ni elements (1 <= i <= m) in ascending order from left to right, and the elements from the same column are in ascending order from bottom to top.
An example of Young table for m = 4, n1 = 6, n2 = 4, n3 = 4, n4 = 1 is the following:
1 2 59 10 15
3 6 713
4 8 1214
11
Given n1, n2, ..., nm determine the number of Young tables containing the elements 1, 2, ..., n1+n2+...+nm.
Input
The input has the stucture:
on the first line is: the natural number m (1 <= m <= 20);
on the second line are: the numbers n1, n2, ..., nm separated by a space (n1 <= 12).
Output
The output will contain the number of Young tables that can be built.
Sample Input
2
3 2
Sample Output
5
解法:
暴力搜索,只要满足(*)中的条件就可以了
#include<iostream>
#include<fstream>
#include<cstdlib>
using namespace std;
ifstream fin("C:\\data42.in");
int m,n[20];
int total,cnt;
int table[21][13];
int isChosen[241]; //这个数组的作用见《算法竞赛入门》P111T6.4.3,里面有讲解
void young(int row,int col)
{
if(row>m)
{
++cnt;
return;
}
int& val=table[row][col];
int sign=val;
for(val=table[row][col-1]+1;val<=total;++val)
{
if(val>table[row][col-1]&&val>table[row-1][col])
{
if(isChosen[val]==0)
{
isChosen[val]=1;
if(col<n[row])
young(row,col+1);
else
young(row+1,1);
isChosen[val]=0;
}
}
}
}
int main()
{
fin>>m;
total=0;
cnt=0;
for(int i=1;i<=m;++i)
{
fin>>n[i];
total+=n[i];
}
memset(table,0,sizeof(table));
memset(isChosen,0,sizeof(isChosen));
young(1,1);
cout<<cnt<<endl;
system("pause");
return 0;
}