首先先看题目。
链接:https://ac.nowcoder.com/acm/contest/5633/A
来源:牛客网
一个长度为n+m+k包含n个数字1,m个数字2和k个数字4的数组,最多可能有多少个子序列1412? 如果一个序列是数组的子序列,当且仅当这个序列可以由数组删去任意个元素,再将数组中的剩余元素按顺序排列而成。
输入描述:
第一行一个整数t,表示测试用例的组数。接下来t行每行三个整数n,m,k表示一组测试用例。
输出描述:
对于每组测试用例输出一行一个整数表示答案。
示例1
输入
3
6 7 8
1 2 2
6 0 3
输出
504
0
0
备注:
1<=t<=200000,0<=n,m,k<=10000
我们要理解题意,是在一个序列中删去人一个数组使序列变成1412。
例如一个序列114444122,我们想要获得子序列1412,就要删去前面两个1的其中一个,四个4中的其中三个4以及最后的两个2中的其中一个2。
那我们是否可以换种思路,我们不是删除序列中多余的数,而是从序列中提取我们需要的序列。如上一个序列114444122,我们需要的是1412,所以我们从前面板两个1中选取一个,有两种可能,四个4中选取一个4,有四种可能,中间的1只有一个,一种可能,最后的2有两种可能。所以它的1412子序列有2x4x1x2=16种。
而题目中给我们的是n个数字1,但是我们需要的序列1412前面和中间各有一个1,所以最恰当的方法是前面和中间各放置n/2个1。得到序列n/2个1,k个4,n/2个1,m个2,再运用上述方法得到子序列1412的个数。
例如示例中的例子,6个1,7个2,8个4,按照我们的分配方法,即3个1,8个4,3个1,7个2,所以子序列1412的个数为3x8x3x7=504。
但是有一个问题,就是当1为奇数个的时候,单纯的n/2会使1的个数少一个,所以书写代码时要区分n%2==1与n%2==0的情况,前一种情况是分配n/2+1个1,k个4,n/2个1,m个2。
当你理解题意之后就完成签到啦。
代码如下PS(不一定用long,我只是在内存允许范围内防止溢出):
include
using namespace std;
int main()
{
long r;
cin >> r;
long* p = new long[r];
for (int y = 0; y < r; y++)
{
p[y] = new long[3];
}
for (long i = 0; i < r; i++)
{
cin >> p[i][0]>>p[i][1]>>p[i][2];
}
for (long j = 0; j < r; j++)
{
if ( p[j][0]% 2 == 1)
cout << (p[j][0] / 2 + 1) * p[j][1] * p[j ][ 2] * (p[j][0] / 2) << endl;
else
cout << (p[j][0] / 2) * p[j ][ 1] * p[j ][2] * (p[j][0] / 2) << endl;
}
}