列表

详情


NC16888. [NOI2001]陨石的秘密

描述

公元11380年,一颗巨大的陨石坠落在南极。于是,灾难降临了,地球上出现了一系列反常的现象。当人们焦急万分的时候,一支中国科学家组成的南极考察队赶到了出事地点。经过一番侦察,科学家们发现陨石上刻有若干行密文,每一行都包含5个整数: 
1 1 1 1 6 
0 0 6 3 57 
8 0 11 3 2845 
著名的科学家SS发现,这些密文实际上是一种复杂运算的结果。为了便于大家理解这种运算,他定义了一种SS表达式: 
1.    SS表达式是仅由'{','}','[',']','(',')'组成的字符串。 
2.    一个空串是SS表达式。 
3.    如果A是SS表达式,且A中不含字符'{','}','[',']',则(A)是SS表达式。 
4.    如果A是SS表达式,且A中不含字符'{','}',则[A]是SS表达式。 
5.    如果A是SS表达式,则{A}是SS表达式。 
6.    如果A和B都是SS表达式,则AB也是SS表达式。 


例如 
()(())[] 
{()[()]} 
{{[[(())]]}} 
都是SS表达式。 
而 
()([])() 
[() 
不是SS表达式。 

一个SS表达式E的深度D(E)定义如下: 
 
例如(){()}[]的深度为2。 

密文中的复杂运算是这样进行的: 
设密文中每行前4个数依次为L1,L2,L3,D,求出所有深度为D,含有L1对{},L2对[],L3对()的SS串的个数,并用这个数对当前的年份11380求余数,这个余数就是密文中每行的第5个数,我们称之为?神秘数?。 
密文中某些行的第五个数已经模糊不清,而这些数字正是揭开陨石秘密的钥匙。现在科学家们聘请你来计算这个神秘数。 

输入描述

共一行,4个整数L1,L2,L3,D。相邻两个数之间用一个空格分隔。
(0 <= L1 <= 10,0 <= L2 <= 10,0 <= L3 <= 10,0 <= D <= 30)

输出描述

共一行,包含一个整数,即神秘数。

示例1

输入:

1 1 1 2

输出:

8

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 48ms, 内存消耗: 604K, 提交时间: 2020-07-04 09:45:49

#include<iostream>
#include<cstdio>
#define mod 11380
using namespace std;
int n,l1,l2,l3,D,f[11][11][11][31];
int main(){
	scanf("%d%d%d%d",&l1,&l2,&l3,&D);
	f[0][0][0][0]=1;
	for(int i=0;i<=l1;i++){
		for(int j=0;j<=l2;j++){
			for(int k=0;k<=l3;k++){
				for(int l=1;l<=D;l++){
					if(i!=0||j!=0||k!=0){
						int tmp=0;
						for(int a=0;a<k;a++){
							tmp=(tmp+f[i][j][k-a-1][l]*f[0][0][a][l-1])%mod;
						}
						for(int b=0;b<j;b++){
							for(int a=0;a<=k;a++)
							tmp=(tmp+f[i][j-b-1][k-a][l]*f[0][b][a][l-1])%mod;
						}
						for(int c=0;c<i;c++){
							for(int b=0;b<=j;b++){
								for(int a=0;a<=k;a++){
									tmp=(tmp+f[i-c-1][j-b][k-a][l]*f[c][b][a][l-1])%mod;
								}
							}
						}
						f[i][j][k][l]=tmp;
					}
					else f[i][j][k][l]=1;
				}
			}
		}
	}
	int ans=((f[l1][l2][l3][D]-f[l1][l2][l3][D-1])%mod+mod)%mod;
	printf("%d\n",ans);
	return 0;
}

C++(g++ 7.5.0) 解法, 执行用时: 37ms, 内存消耗: 640K, 提交时间: 2022-08-13 16:32:19

#include<bits/stdc++.h>
using namespace std;
const int mod=11380;
int dp[15][15][15][35];
int f(int a,int b,int c,int d)
{
    if(a==0&&b==0&&c==0)
    return 1;
    int tmp=0;
    for(int i=1;i<=c;i++)
    tmp=(tmp+dp[a][b][c-i][d]*dp[0][0][i-1][d-1])%mod;
    for(int i=1;i<=b;i++)
    for(int j=0;j<=c;j++)
    tmp=(tmp+dp[a][b-i][c-j][d]*dp[0][i-1][j][d-1])%mod;
    for(int i=1;i<=a;i++)
    for(int j=0;j<=b;j++)
    for(int k=0;k<=c;k++)
    tmp=(tmp+dp[a-i][b-j][c-k][d]*dp[i-1][j][k][d-1])%mod;
    return tmp;
}
int main()
{
    int a,b,c,n;
    scanf("%d %d %d %d",&a,&b,&c,&n);
    dp[0][0][0][0]=1;
    for(int i=0;i<=a;i++)
    for(int j=0;j<=b;j++)
    for(int k=0;k<=c;k++)
    for(int l=1;l<=n;l++)
    dp[i][j][k][l]=f(i,j,k,l);
    printf("%d",n?(dp[a][b][c][n]-dp[a][b][c][n-1]+mod)%mod:dp[a][b][c][n]);
}

C++11(clang++ 3.9) 解法, 执行用时: 43ms, 内存消耗: 748K, 提交时间: 2020-03-02 19:38:27

#include<bits/stdc++.h>
using namespace std;
const int mod=11380;
int dp[15][15][15][35];
int f(int a,int b,int c,int d)
{
	if(a==0&&b==0&&c==0)
	return 1;
	int tmp=0;
	for(int i=1;i<=c;i++)
	tmp=(tmp+dp[a][b][c-i][d]*dp[0][0][i-1][d-1])%mod;
	for(int i=1;i<=b;i++)
	for(int j=0;j<=c;j++)
	tmp=(tmp+dp[a][b-i][c-j][d]*dp[0][i-1][j][d-1])%mod;
	for(int i=1;i<=a;i++)
	for(int j=0;j<=b;j++)
	for(int k=0;k<=c;k++)
	tmp=(tmp+dp[a-i][b-j][c-k][d]*dp[i-1][j][k][d-1])%mod;
	return tmp;
}
int main()
{
	int a,b,c,n;
	scanf("%d %d %d %d",&a,&b,&c,&n);
	dp[0][0][0][0]=1;
	for(int i=0;i<=a;i++)
	for(int j=0;j<=b;j++)
	for(int k=0;k<=c;k++)
	for(int l=1;l<=n;l++)
	dp[i][j][k][l]=f(i,j,k,l);
	printf("%d",n?(dp[a][b][c][n]-dp[a][b][c][n-1]+mod)%mod:dp[a][b][c][n]);
}

上一题