• [POJ1187] 陨石的秘密


    问题描述

    公元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 2

    样例输出

    8

    题解

    显然是一道动态规划的题目。对于这些变量,设(f[i][j][k][d])表示串中有i个()、j个[]、k个{}、深度不大于d时的方案总数。由定义可知,两个SS串拼在一起也是一个SS串,我们可以借此来进行动态规划。但是,若一个SS串为ABC,在计算时就会将AB+C和A+BC作为两个方案计算在内,但实际上是同一种方案。因此,为了避免重复,可以在动态规划时令一个串强制在最外面加上一个括号(满足要求的最小括号)。所以,首先枚举一个串中有的每种括号的数量,然后把所有括号分成两部分,对答案的贡献即为分成的两个串的乘积。注意取模。

    代码

    #include <iostream>
    #include <cstdio>
    using namespace std;
    const int mod=11380;
    int l1,l2,l3,d,f[12][12][12][32],i,j,k,l,a,b,c;
    int main()
    {
    	cin>>l1>>l2>>l3>>d;
    	f[0][0][0][0]=1;
    	for(i=0;i<=l1;i++){
    		for(j=0;j<=l2;j++){
    			for(k=0;k<=l3;k++){
    				for(l=1;l<=d;l++){
    					if(i!=0||j!=0||k!=0){
    						int tmp=0;
    						for(a=0;a<k;a++) tmp=(tmp+f[i][j][k-a-1][l]*f[0][0][a][l-1])%mod;
    						for(a=0;a<j;a++){
    							for(b=0;b<=k;b++) tmp=(tmp+f[i][j-a-1][k-b][l]*f[0][a][b][l-1])%mod;
    						}
    						for(a=0;a<i;a++){
    							for(b=0;b<=j;b++){
    								for(c=0;c<=k;c++) tmp=(tmp+f[i-a-1][j-b][k-c][l]*f[a][b][c][l-1])%mod;
    							}
    						}
    						f[i][j][k][l]=tmp;
    					}
    					else f[i][j][k][l]=1;
    				}
    			}
    		}
    	}
    	int ans=0;
    	if(d>0) ans=(f[l1][l2][l3][d]-f[l1][l2][l3][d-1]+mod)%mod;
    	else ans=f[l1][l2][l3][d];
    	cout<<ans<<endl;
    	return 0;
    }
    
  • 相关阅读:
    python
    【转载】【CPU】关于x86、x86_64/x64、amd64和arm64/aarch64
    【百思不得其解1】诡异的速度差异
    LeakCanary 与 鹅场Matrix ResourceCanary对比分析
    android 插件化框架VitualAPK
    android高级篇收录
    滴滴Booster移动APP质量优化框架 学习之旅 三
    滴滴Booster移动APP质量优化框架 学习之旅 二
    滴滴Booster移动APP质量优化框架 学习之旅
    不一样视角的Glide剖析
  • 原文地址:https://www.cnblogs.com/LSlzf/p/10659992.html
Copyright © 2020-2023  润新知