ACM 简单DP Pole Arrangement Regionals 2012 >> Asia - Daejeon 区域赛

来源:互联网 发布:ipython for windows 编辑:程序博客网 时间:2024/06/05 09:34

Pole Arrangement

https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=585&page=show_problem&problem=4128

Regionals 2012 >> Asia - Daejeon6117 Pole Arrangement


There are poles of height 1; 2; : : : ; n in a row. If you look at these poles from the left side or the right
side, smaller poles are hidden by taller poles. For example, consider the two arrangements of 4 poles in
the next gure:
For each arrangement, only one pole can be seen from the left, and two poles can be seen from the
right.
You are to write a program to calculate the number of arrangements of n poles such that seen from
the left you see l poles and seen from the right you see r poles.
Input
Your program is to read from standard input. The input consists of T test cases. The number of test
cases T is given in the rst line of the input. Each test case consists of a line containing three integers,
n, l, and r (1  l; r  n  20), where n is the number of poles and l (resp. r) is the number of poles
that can be seen from the left (resp. right).
Output
Your program is to write to standard output. Print exactly one line for each test case. The line should
contain the number of arrangements of poles for the test case.
The following shows sample input and output for four test cases.
Sample Input
4
4 1 2
4 1 1
5 2 4
20 2 1
Sample Output
2
0
4
6402373705728000

There are poles of height 1; 2; : : : ; n in a row. If you look at these poles from the left side or the right
side, smaller poles are hidden by taller poles. For example, consider the two arrangements of 4 poles in
the next gure:
For each arrangement, only one pole can be seen from the left, and two poles can be seen from the
right.
You are to write a program to calculate the number of arrangements of n poles such that seen from
the left you see l poles and seen from the right you see r poles.
Input
Your program is to read from standard input. The input consists of T test cases. The number of test
cases T is given in the rst line of the input. Each test case consists of a line containing three integers,
n, l, and r (1  l; r  n  20), where n is the number of poles and l (resp. r) is the number of poles
that can be seen from the left (resp. right).
Output
Your program is to write to standard output. Print exactly one line for each test case. The line should
contain the number of arrangements of poles for the test case.
The following shows sample input and output for four test cases.
Sample Input
4
4 1 2
4 1 1
5 2 4
20 2 1
Sample Output
2
0
4

6402373705728000

显然最高的一个杆子,一定是左右都可以看得到的

显然是三维状态DP,两种方法:

1.将新加入的第N个元素当成是最小的,原来n-1个元素变成大一个 

f[i][j][k]=(i-2)*f[i-1][j][k]+f[i-1][j-1][k]+f[i-1][j][k-1];

O(n^3)

2.将新加入的第N个元素当成是最大的,运用枚举左边(右边)的个数,用到组合公式‘

O(n^4)

第一种更优,实现更简单,不要惯性思维


O(n^3)
/* * Author: NICK WONG * Created Time:  7/27/2014 14:37:52 * File Name: h.cpp */#include<iostream>#include<sstream>#include<fstream>#include<vector>#include<list>#include<deque>#include<queue>#include<stack>#include<map>#include<set>#include<bitset>#include<algorithm>#include<cstdio>#include<cstdlib>#include<cstring>#include<cctype>#include<cmath>#include<ctime>#include<iomanip>#define out(x) cout << #x << x <<endl;using namespace std;const double eps(1e-8);typedef long long LL;const int maxn=110;const long long maxint=-1u>>1;const long long maxlong=maxint*maxint;long long c[maxn][maxn],f[maxn][maxn][maxn],n,l,r;void work(){    memset(f,0,sizeof(f));    cin >> n >> l >> r;    f[1][1][1]=1;    for (int i=2; i<=n; i++)        for (int j=1; j<=n; j++)            for (int k=1; k<=n; k++)                f[i][j][k]=(i-2)*f[i-1][j][k]+f[i-1][j-1][k]+f[i-1][j][k-1];    cout << f[n][l][r] << endl;}int main(){    int t;    cin >> t;    while (t--) work();     return 0;}


O(n^4)/* * Author: NICK WONG * Created Time:  7/27/2014 14:37:52 * File Name: h.cpp */#include<iostream>#include<sstream>#include<fstream>#include<vector>#include<list>#include<deque>#include<queue>#include<stack>#include<map>#include<set>#include<bitset>#include<algorithm>#include<cstdio>#include<cstdlib>#include<cstring>#include<cctype>#include<cmath>#include<ctime>#include<iomanip>#define out(x) cout << #x << x <<endl;using namespace std;const double eps(1e-8);typedef long long LL;const int maxn=110;const long long maxint=-1u>>1;const long long maxlong=maxint*maxint;long long c[maxn][maxn],f[maxn][maxn][maxn];int n,l,r;void work(){    memset(f,0,sizeof(f));    cin >> n >> l >> r;    for (int i=0; i<=20; i++) c[i][0]=1;    for (int i=1; i<=20; i++)        for (int j=1; j<=i; j++)            c[i][j]=c[i-1][j-1]+c[i-1][j];    /*for (int i=1; i<=20; i++)        for (int j=1; j<=i; j++)            if (j==i) cout << c[i][j] << endl; else cout << c[i][j] << " ";*/    f[0][0][0]=1;    for (int i=1; i<=n; i++)    {        for (int j=1; j<=i; j++)            for (int k=1; k<=i+1-j; k++)                for (int x=j-1; x<=i-k; x++)                    f[i][j][k]+=c[i-1][x]*f[x][j-1][0]*f[i-1-x][0][k-1];        for (int j=1; j<=i; j++)            for (int k=1; k<=i+1-j; k++)            {                f[i][j][0]+=f[i][j][k];                f[i][0][k]+=f[i][j][k];                //out(f[i][j][k]);            }    }    cout << f[n][l][r] << endl;}int main(){    int t;    cin >> t;    while (t--) work();     return 0;}


0 0
原创粉丝点击