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 赛后的经验总结 // 比赛完才 ...
随机推荐
- Codeforces 812E Sagheer and Apple Tree ——(阶梯博弈)
之前在bc上做过一道类似的阶梯博弈的题目,那题是移动到根,这题是移动到叶子.换汤不换药,只要和终态不同奇偶的那些位置做nim即可.因此这题给出了一个条件:所有叶子深度的奇偶性相同.同时需要注意的是,上 ...
- Js 之复制到剪贴板 clipboard.js
一.下载 https://github.com/zenorocha/clipboard.js/archive/master.zip 二.Demo示例 <!DOCTYPE html> < ...
- Linux设备驱动程序 之 get_free_page
get_free_page 如果模块需要分配大块的内存,使用面向页的分配会有很多优点: 分配页面可使用下面的函数: unsigned long get_zeroed_page(gfp_t gfp_ma ...
- Facebook币Libra学习-1.核心概念
Libra区块链是一个基于Libra协议的加密认证的分布式数据库.本文将简略介绍Libra协议的核心概念.其详细说明请参阅Libra技术白皮书. Libra区块链由分布式的Validator节点网络维 ...
- 【matlab】模拟变焦拼接代码备份
1.初版,边缘未处理. % % In----near % If----far % In=imread('D:\文件及下载相关\桌面\模拟变焦拼接\Matlab_code\nearframe\frame ...
- SQL-W3School-高级:SQL CREATE INDEX 语句
ylbtech-SQL-W3School-高级:SQL CREATE INDEX 语句 1.返回顶部 1. CREATE INDEX 语句用于在表中创建索引. 在不读取整个表的情况下,索引使数据库应用 ...
- smarty里通过循环section嵌套结合IF语句实现工程进度显示
<ul class="site_ul"> <{section name=constructionlist loop=$ly}> <li class=& ...
- python图论包networks(最短路,最小生成树带包)
官方文档: https://networkx.github.io/documentation/networkx-1.10/reference/algorithms.html 最短路和最小生成树: im ...
- 关于对VGA、DVI、HDMI的区别
VGA接口: DVI接口: HDMI接口 可以这么理解: 1. VGA传输普通视频信号,DVI传输高清视频信号,HDMI传输高清视频信号并支持音频传输.2. HDMI的三种接口只有大小区别,功能没有任 ...
- nginx反向代理本地 两台web负载均衡 使用域名代理
环境: 本地外网ip:123.58.251.166 .配置index.html网页 [root@host---- conf.d]# cat /web/sing/index.html <h1> ...