本文主要是介绍试题 算法训练 Sereja and Squares,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
题目链接 试题 算法训练 Sereja and Squares
参考博客 https://www.luogu.com.cn/problemnew/solution/CF314E
资源限制
时间限制:4.0s 内存限制:256.0MB
问题描述
Sereja在平面上画了n个点,点i在坐标(i,0)。然后,Sereja给每个点标上了一个小写或大写英文字母。Sereja不喜欢字母"x",所以他不用它标记点。Sereja认为这些点是漂亮的,当且仅当:
·所有的点可以被分成若干对,使得每个点恰好属于一一对之中。
·在每对点中,横坐标较小的会被标上小写字母,较大的会被标上对应的大写字母。
·如果我们在每对点上画一个正方形,其中已知的一对点会作为正方形的相对的顶点,它们间的线段会成为正方形的对角线,那么在所有画出的正方形中不会有相交或触碰的情况。
小Petya擦掉了一些小写字母和所有大写字母,现在Sereja想知道有多少种方法来还原每个点上的字母,使得还原后这些点是漂亮的。
输入格式
第一行是一个整数n,表示点的个数。
第二行是一个长度为n的字符串,包含小写字母和问号"?",是按照横坐标递增的顺序的每个点的描述。问号表示这个点的字母被Petya擦掉了。保证输入串不含字母"x"。
输出格式
输出答案对4294967296取模的值。如果没有可行的方案,输出0。
样例输入
4
a???
样例输出
50
样例输入
4
abc?
样例输出
0
样例输入
6
abc???
样例输出
1
数据规模和约定
20个测试点的n分别为:
5,10,20,50,100,
200,500,1000,2000,5000,
10000,20000,30000,40000,50000,
60000,70000,80000,90000,100000.
解题思路
左括号与右括号的个数都应该是 n / 2.若n为奇数,则无解.
取模:因为对 4294967296 即 2 ^ 32 取模,我们可以用 unsigned int,但不要所有数都开这个东西,常数太大会TLE.
问题转换,我们可以把小写字母看成左括号,大写字母看成右括号。总共有25种(除开x、X)。
首先我们来看n^2的括号序列的做法。
- 我们设状态 f(i, j) 表示已经考虑了前i个数,现在还有j个左括号没有匹配的方案数.
- 则可以有两种转移情况:1.第 i + 1 个数是左括号,则可以转移为 f[i+1][j+1]. 2.第 i + 1 个数是问号,则可以转移为 f[i+1][j-1]与f[i+1][j+1] .
我们再来看这道题的情况.这与上面传统情况的不同之处是他擦去了所有的右括号以及一部分的左括号.
令 f(i, j) 表示 假设括号只有一种,前 i 个数里面,填了 j 个右括号的方案数.
第i个数是问号,当前位置填左括号 f[i][j]+=f[i-1][j],当前位置填右括号f[i][j]+=f[i-1][j-1]
f[n][n/2]即为答案
利用一种情况的方案数计算多种括号的方案数.
我们开文章一开始就说了,我们有25种括号,且左括号个数是 n / 2 个.
假设序列中已有 p 个左括号,那么 ?(即要填的数的个数) 里面就有 n / 2 - p 个左括号.
每一个左括号有 25 种选择,那么 ans = 25 ^ (n / 2 - q) * f(n, n / 2).
程序代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define LL unsigned int
using namespace std;
int n,p;
LL f[200005]={1},ans=1;
char c[100005];
int main() {cin>>n;cin>>c+1;if(n&1) cout<<"0"<<endl;else {int m=n>>1;for(int i=1;i<=n;++i){if(c[i]=='?') for(int j=i>>1;j>=i-m&&j;j--){f[j]+=f[j-1];//统计各种填右括号的方法个数//并且把f[i]这一层去掉了,滚动着来的。}else p++;//计算已经填写的小写字母的个数}for(int i=1;i<=m-p;i++) {ans=ans*25;//每个能够填写小写字母的地方都有25种填法}ans=(ans*f[m]);//将结果相乘cout<<(LL)ans<<endl;}return 0;
}
这篇关于试题 算法训练 Sereja and Squares的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!