2019上海网络赛 F. Rhyme scheme 普通dp
Rhyme scheme
Problem Describe
A rhyme scheme is the pattern of rhymes at the end of each line of a poem or song. It is usually referred to by using letters to indicate which lines rhyme; lines designated with the same letter all rhyme with each other.
e.g., the following "poem'' of 4 lines has an associated rhyme scheme "ABBA''
1 —— 99 bugs in the code A
2 —— Fix one line B
3 —— Should be fine B
4 —— 100 bugs in the code A
This essentially means that line 1 and 4 rhyme together and line 2 and 3 rhyme together.
The number of different possible rhyme schemes for an nnn-line poem is given by the Bell numbers. For example, \(B_3 = 5\), it means there are five rhyme schemes for a three-line poem: AAA, AAB, ABA, ABB, and ABC.
The question is to output the \(k\)-th rhyme scheme in alphabetical order for a poem of nnn lines.For example: the first rhyme scheme of a three-line poem is "AAA'', the fourth rhyme scheme of a three-line poem is ABB''.
InputFile
The first line of the input gives the number of test cases, T(\(1 \leq T \leq 10000\)). T test cases follow.
Each test case contains a line with two integers nnn and \(k\).
\(1 \leq n \leq 26, 1 \leq k \leq B_n\) (\(B_n\) is the \(n\)-th of Bell numbers)
OutputFile
For each test case, output one line containing Case #x: y, where x is the test case number (starting from 1) and y is the rhyme scheme contains uppercase letters.
样例输入
7
1 1
2 1
3 1
3 2
3 3
3 4
3 5
样例输出
Case #1: A
Case #2: AA
Case #3: AAA
Case #4: AAB
Case #5: ABA
Case #6: ABB
Case #7: ABC
题意
就是求第k个排列,但是有些排列是重复的,比如AAB和AAC算一种(如果不能理解可以看看题目)
题解
这里其实都是瞎扯
我一开始想的就是求当\(n=26\)时总共有多少种不同的排列。然后想了个dp,然后想用递归,每次确定第一位选什么,然后再做后面的。但是我的两个队友听到我的想法都说不懂,然后看别的题了,然后我就一个人想啊想,一路上遇到了许多问题,还好最后还是解决了。
首先我们需要发现一些性质:
- 长度为n的字符串,只会用n种字母,这个性质很明显也很重要。
- 每个字符串的种类会因为前面的不同而变化,比如aaa后面接两种字母a、b,而aab后面可以接a、b、c.
- 我们只要前面字符串用过的种类数以及后面字符串的长度,后面字符串的种类也就确定了
- 有人可能会觉得要是前面字符串用a、b、c和用a、b、d都是三种但是不一样,但是a、b、d是不会出现的(可以结合第一点想想)
以上的性质可不是那么容易就能明白的,所以请结合具体例子仔细想想。
题解正式开始
先说说dp的预处理吧:
- \(\Large 定义:\) \(dp[n][m] [h]\)用m种字母组成长度为m的字符串,字符串前面接一个用了h种字母的字符串(不在乎前面的字符串的长度)。
- \(\Large 转移方程:\)\(dp[n][m][h]=dp[n][m-1][h]+dp[n][m][h]*m\)
- \(\Large初始化:\) \(dp[0][0][h]=h\)
然后定义\(f[n][h]\)为\(sum(dp[n][1..m][h])\),之后开始从第一位开始枚举,字符从小到大的开始枚举。
我这里是用的的递归,void find(n,k,h) 即前面的字符串用了h种字符,求接下n个字母组成的字符串的第k个排列。
然后一层层做下去,直到\(n=0\) 结束
ps:会爆int64,于是我用了int128;还有就是我并没有讲的太清楚,只是讲了主要思想和具体实现,至于怎么想到的,那我也不清楚。
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
template<typename T>void read(T&x)
{
ll k=0; char c=getchar();
x=0;
while(!isdigit(c)&&c!=EOF)k^=c=='-',c=getchar();
if (c==EOF)exit(0);
while(isdigit(c))x=x*10+c-'0',c=getchar();
x=k?-x:x;
}
void read_char(char &c)
{while(!isalpha(c=getchar())&&c!=EOF);}
__int128 f[28][28],dp[28][28][28],k;
ll n;
void init()//预处理部分
{
for(ll i=0;i<=26;i++)dp[0][i][i]=1;
for(ll h=0;h<=26;h++)
for(ll i=1;i<=26;i++)
for(ll j=1;j<=26;j++)
dp[i][j][h]=dp[i-1][j][h]*j+dp[i-1][j-1][h];
for(ll h=0;h<=26;h++)
for(ll i=0;i<=26;i++)
for(ll j=0;j<=26;j++)
f[i][h]+=dp[i][j][h];
}
void Find(ll n,__int128 k,ll h)//递归求解
{
if (n==0)return;
ll tp=(k-1)/f[n-1][h];
if (tp+1<=h)//格外注意h=0的时候
{
printf("%c",'A'+(int)(tp));
Find(n-1,k-tp*f[n-1][h],h);
}
else
{
printf("%c",'A'+(int)(h));
Find(n-1,k-h*f[n-1][h],h+1);
}
}
void work()
{
static int cas=0;
printf("Case #%d: ",++cas);
read(n); read(k);
ll p=0;
Find(n,k,p);
if (cas)printf("\n");
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("aa.in","r",stdin);
#endif
init();
int T;
read(T);
while(T--)work();
}
2019上海网络赛 F. Rhyme scheme 普通dp的更多相关文章
- 2019 上海网络赛 F Rhyme scheme (字典树DP)
题目:https://nanti.jisuanke.com/t/41414 题意:求长度为n的第k个bell number , 就是第i位的选取范围在 1-(i-1)位的最大值 +1,第一位固定为 ...
- [2019上海网络赛F题]Rhyme scheme
题目链接 题意,求出合法的长度为n的字典序第k小字符串,合法的定义为除了最后一位,每一位的取值范围为'A'到'A'+pos-1,而最后一位的取值范围'A'到当前字符串最大值+1. 队友tql,Orz ...
- ACM-ICPC 2019南昌网络赛F题 Megumi With String
ACM-ICPC 南昌网络赛F题 Megumi With String 题目描述 给一个长度为\(l\)的字符串\(S\),和关于\(x\)的\(k\)次多项式\(G[x]\).当一个字符串\(str ...
- 2019上海网络赛B题(差分 + 离散化 or 差分 + 思维)
这题.....队里都没怎么训练差分,导致败北...写了一堆线段树嘤嘤嘤,到最后也是超时,比赛结束后看到了差分的思想于是就去学了一手. 其实了解差分思想的一眼就能看出来是差分了.但是如果对n差分的话很明 ...
- [2019上海网络赛J题]Stone game
题目链接 CSLnb! 题意是求出给定集合中有多少个合法子集,合法子集的定义为,子集和>=总和-子集和$\& \&$子集和-(子集的子集和)<=总和-子集和. 其实就是很简 ...
- 2019 上海网络赛 J stone name (01背包)
题目:https://nanti.jisuanke.com/t/41420 题意:给你一个集合,然后让你拆成两个集合 x,y 求满足 x>y && x-(x集合中最小 ...
- 2019南昌网络赛I:Yukino With Subinterval(CDQ) (树状数组套主席树)
题意:询问区间有多少个连续的段,而且这段的颜色在[L,R]才算贡献,每段贡献是1. 有单点修改和区间查询. 思路:46min交了第一发树套树,T了. 稍加优化多交几次就过了. 不难想到,除了L这个点, ...
- ACM-ICPC 2019南昌网络赛I题 Yukino With Subinterval
ACM-ICPC 2019南昌网络赛I题 Yukino With Subinterval 题目大意:给一个长度为n,值域为[1, n]的序列{a},要求支持m次操作: 单点修改 1 pos val 询 ...
- ICPC 2019 徐州网络赛
ICPC 2019 徐州网络赛 比赛时间:2019.9.7 比赛链接:The Preliminary Contest for ICPC Asia Xuzhou 2019 赛后的经验总结 // 比赛完才 ...
随机推荐
- Dubbo——基础
一.分布式基础理论 1.1 什么是分布式系统? “分布式系统是若干独立计算机的集合,这些计算机对于用户来说就像单个相关系统” 分布式系统(distributed system)是建立在网络之上的软件系 ...
- Robot Framework(十七) 扩展RobotFramework框架——扩展Robot Framework Jar
4.4扩展Robot Framework Jar 使用标准JDK安装中包含的jar命令,可以非常简单地向Robot Framework jar添加其他测试库或支持代码.Python代码必须放在jar里 ...
- POJ 2778 DNA Sequence —— (AC自动机+矩阵快速幂)
距离上次做AC自动机有很久了=.=,以前这题的思路死活看不懂,现在还是觉得很好理解的. 思路参见:http://blog.csdn.net/morgan_xww/article/details/783 ...
- Python——装饰器(Decorator)
1.什么是装饰器? 装饰器放在一个函数开始定义的地方,它就像一顶帽子一样戴在这个函数的头上.和这个函数绑定在一起.在我们调用这个函数的时候,第一件事并不是执行这个函数,而是将这个函数做为参数传入它头顶 ...
- COM组件双接口对象模型
模型如下: 这里COM对象一共实现了三个接口,IUnknown,IDispatch, Ixxx. 每个COM都必须实现IUnknown,不考虑在内的话共实现了IDispatch和自定义接口Ixxx两个 ...
- dd 命令
dd:用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换. 注意:指定数字的地方若以下列字符结尾,则乘以相应的数字:b=512:c=1:k=1024:w=2 参数注释: if=文件名:输入文件名 ...
- [Java复习] Spring IoC
1. Spring bean的生命周期? 1. 对Bean进行实例化(相当于new) 对于BeanFactory 当客户向容器请求一个尚未初始化的bean(或初始化bean需要注入另外一个尚未初始化的 ...
- SQL语句中有关单引号、双引号和加号的问题
字符串数据是用单引号包在外面的,而+号只是用来连接这些字符串的. 数据库里的字段是整型的时候不要加单引号,是字符串的时候要加,其它类型根据实际情况来,双引号就是用来拼接字符串的,单引号是sql文的固有 ...
- Qt编写数据可视化大屏界面电子看板11-自定义控件
一.前言 说到自定义控件,我是感觉特别熟悉的几个字,本人亲自原创的自定义控件超过110个,都是来自各个行业的具体应用真实需求,而不是凭空捏造的,当然有几个小控件也有点凑数的嫌疑,在编写整个数据可视化大 ...
- 处理HTTP请求
处理HTTP请求 当客户端浏览器通过URL访问web应用时,首先要做的就是获取用户提交的信息,也就是从HTTP请求数据中获得的信息.HTTP请求数据分为HTTP请求头和Body HTTP请求头包含了一 ...