洛谷题目链接:[USACO5.5]贰五语言Two Five

题目描述

有一种奇怪的语言叫做“贰五语言”。它的每个单词都由A~Y这25个字母各一个组成。但是,并不是任何一种排列都是一个合法的贰五语言单词。贰五语言的单词必须满足这样一个条件:把它的25个字母排成一个5*5的矩阵,它的每一行和每一列都必须是递增的。比如单词ACEPTBDHQUFJMRWGKNSXILOVY,它排成的矩阵如下所示:

A C E P T

B D H Q U

F J M R W

G K N S X

I L O V Y

因为它的每行每列都是递增的,所以它是一个合法的单词。而单词YXWVUTSRQPONMLKJIHGFEDCBA则显然不合法。 由于单词太长存储不便,需要给每一个单词编一个码。编码方法如下:从左到右,再从上到下,可以由一个矩阵的得到一个单词,再把单词按照字典顺序排序。比如,单词ABCDEFGHIJKLMNOPQRSTUVWXY的编码为1,而单词ABCDEFGHIJKLMNOPQRSUTVWXY的编码为2。

现在,你需要编一个程序,完成单词与编码间的转换。

输入输出格式

输入格式:

第一行为一个字母N或W。N表示把编码转换为单词,W表示把单词转换为编码。

若第一行为N,则第二行为一个整数,表示单词的编码。若第一行为W,则第二行为一个合法的单词。

输出格式:

每行一个整数或单词。

输入输出样例

输入样例#1:

N

2

输出样例#1:

ABCDEFGHIJKLMNOPQRSUTVWXY

输入样例#2:

W

ABCDEFGHIJKLMNOPQRSUTVWXY

输出样例#2:

2

说明

题目翻译来自NOCOW。

USACO Training Section 5.5

题解: 我尝试过爆搜,但是在我\(A\)了这题之后都还没枚举完所有情况...

显然这个状态是非常多的,接近\(25!\),所以我们需要将其中一些状态记忆化一下.

我们设\(f[a][b][c][d][e]\)表示第\(1\)行填入了\(a\)个数,第\(2\)行填入了\(b\)个数....的方案.因为我们在填数的时候一定是一个像这样的形状(转自zyzzyzzyzzyz的图):

要填入绿色的块之前一定要先填入黄色的块.

那么我们可以计算出方案数之后,就考虑如何计算答案.我们可以通过类似倍增求\(lca\)的方式来统计答案.回忆一下倍增是如何求\(lca\)的?从大到小枚举向上跳的距离,如果超过了就不跳.这里也是类似的方法.

我们在求方案数的时候会用一个\(vis\)数组来记录某个数字是否可以用,那么在我们修改限制的时候,每次计算出的方案数很显然是会不一样的,这时候就可以用我们上面提到的方法了.

具体细节有点讲不太清,看代码吧.

#include<bits/stdc++.h>
using namespace std; int n, vis[30];
int f[7][7][7][7][7];
char opt, s[30]; bool ok(int x, int num){
return !vis[x] || vis[x] == num;
} int dfs(int a, int b, int c, int d, int e, int x){
if(x == 26) return 1;
if(f[a][b][c][d][e]) return f[a][b][c][d][e];
int res = 0;
if(a <= 5 && ok(a, x)) res += dfs(a+1, b, c, d, e, x+1);
if(b < a && ok(b+5, x)) res += dfs(a, b+1, c, d, e, x+1);
if(c < b && ok(c+10, x)) res += dfs(a, b, c+1, d, e, x+1);
if(d < c && ok(d+15, x)) res += dfs(a, b, c, d+1, e, x+1);
if(e < d && ok(e+20, x)) res += dfs(a, b, c, d, e+1, x+1);
return f[a][b][c][d][e] = res;
} int main(){
int tmp; cin >> opt;
if(opt == 'N'){
cin >> n;
for(int i = 1; i <= 25; i++){
for(vis[i] = 1; ; vis[i]++){
memset(f, 0, sizeof(f));
tmp = dfs(1, 1, 1, 1, 1, 1);
if(tmp >= n) break;
n -= tmp;
}
}
for(int i = 1; i <= 25; i++) cout << (char)(vis[i]-1+'A');
cout << endl;
}
else {
int res = 0; cin >> s+1;
for(int i = 1; i <= 25; i++)
for(vis[i] = 1; vis[i] < s[i]-'A'+1; vis[i]++){
memset(f, 0, sizeof(f));
res += dfs(1, 1, 1, 1, 1, 1);
}
cout << res+1 << endl;
}
return 0;
}

[洛谷P2750] [USACO5.5]贰五语言Two Five的更多相关文章

  1. 洛谷P1345 [USACO5.4]奶牛的电信Telecowmunication【最小割】分析+题解代码

    洛谷P1345 [USACO5.4]奶牛的电信Telecowmunication[最小割]分析+题解代码 题目描述 农夫约翰的奶牛们喜欢通过电邮保持联系,于是她们建立了一个奶牛电脑网络,以便互相交流. ...

  2. [洛谷P1709] [USACO5.5]隐藏口令Hidden Password

    洛谷题目链接:[USACO5.5]隐藏口令Hidden Password 题目描述 有时候程序员有很奇怪的方法来隐藏他们的口令.Binny会选择一个字符串S(由N个小写字母组成,5<=N< ...

  3. [洛谷P2747] [USACO5.4]周游加拿大Canada Tour

    洛谷题目链接:[USACO5.4]周游加拿大Canada Tour 题目描述 你赢得了一场航空公司举办的比赛,奖品是一张加拿大环游机票.旅行在这家航空公司开放的最西边的城市开始,然后一直自西向东旅行, ...

  4. [洛谷P2745] [USACO5.3]窗体面积Window Area

    洛谷题目链接:[USACO5.3]窗体面积Window Area 题目描述 你刚刚接手一项窗体界面工程.窗体界面还算简单,而且幸运的是,你不必显示实际的窗体.有 5 种基本操作: 创建一个新窗体 将窗 ...

  5. 洛谷 P2701 [USACO5.3]巨大的牛棚Big Barn Label:二维数组前缀和 你够了 这次我用DP

    题目背景 (USACO 5.3.4) 题目描述 农夫约翰想要在他的正方形农场上建造一座正方形大牛棚.他讨厌在他的农场中砍树,想找一个能够让他在空旷无树的地方修建牛棚的地方.我们假定,他的农场划分成 N ...

  6. 洛谷1345 [Usaco5.4]奶牛的电信

    题目描述 农夫约翰的奶牛们喜欢通过电邮保持联系,于是她们建立了一个奶牛电脑网络,以便互相交流.这些机器用如下的方式发送电邮:如果存在一个由c台电脑组成的序列a1,a2,...,a(c),且a1与a2相 ...

  7. P2750 贰五语言Two Five USACO5.5 记忆化搜索

    正解:记搜+逼近 解题报告: 神仙题预警,,, 我真滴觉得还是挺难的了,,, 大概说下思路趴QAQ 首先我们要知道逼近法是什么! 逼近法,有点像二分的思路,以这题为例举个eg 假如它给了个数字k.我们 ...

  8. 洛谷 P2746 [USACO5.3]校园网Network of Schools 解题报告

    P2746 [USACO5.3]校园网Network of Schools 题目描述 一些学校连入一个电脑网络.那些学校已订立了协议:每个学校都会给其它的一些学校分发软件(称作"接受学校&q ...

  9. 洛谷——P1345 [USACO5.4]奶牛的电信Telecowmunication

    P1345 [USACO5.4]奶牛的电信Telecowmunication 题目描述 农夫约翰的奶牛们喜欢通过电邮保持联系,于是她们建立了一个奶牛电脑网络,以便互相交流.这些机器用如下的方式发送电邮 ...

随机推荐

  1. Linux 环境下svn 服务器搭建

    可使用自己下载的svn安装包,但要安装相关依赖包,yum 安装源提供的稳定版本svn 1.yum -y install subversion 2.创建本地库 mkdir -p /var/svn svn ...

  2. map的默认排序和自定义排序

    STL的容器map为我们处理有序key-value形式数据提供了非常大的便利,由于内部红黑树结构的存储,查找的时间复杂度为O(log2N). 一般而言,使用map的时候直接采取map<typen ...

  3. lintcode-425-电话号码的字母组合

    425-电话号码的字母组合 Given a digit string excluded 01, return all possible letter combinations that the num ...

  4. CentOS卸载系统自带的OpenJDK并安装Sun的JDK的方法

    查看目前系统的jdk: rpm -qa | grep jdk 得到的结果: [root@dc-01 java]#  rpm -qa | grep jdk java-1.6.0-openjdk-1.6. ...

  5. 转载-C++ vector 用法

    转自:http://www.cnblogs.com/wang7/archive/2012/04/27/2474138.html 在c++中,vector是一个十分有用的容器,下面对这个容器做一下总结. ...

  6. BZOJ 1066:[SCOI2007]蜥蜴(最大流)

    蜥蜴Description在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外. 每行每列中相邻石柱的距离为1,蜥蜴的跳跃距离是d,即蜥蜴可以跳到 ...

  7. 一些兼容性的meta标签

    <!-- 仅针对IOS的Safari顶端状态条的样式(可选default/black/black-translucent )--> <meta name="apple-mo ...

  8. (转)修改Android 的framework层后,重新编译

    1.下面方法适合真机:下载android源码,然后编译你修改的framwork的代码,会生成framework.jar,然后push到system/framework目录下,重启机器!ok 2,下面方 ...

  9. Codeforces Round #405 (rated, Div. 2, based on VK Cup 2017 Round 1)

    A 模拟 B 发现对于每个连通块,只有为完全图才成立,然后就dfs C 构造 想了20分钟才会,一开始想偏了,以为要利用相邻NO YES的关系再枚举,其实不难.. 考虑对于顺序枚举每一个NO/YES, ...

  10. struts2(s2-052)远程命令执行漏洞复现

    漏洞描述: 2017年9月5日,Apache Struts发布最新安全公告,Apache Struts2的REST插件存在远程代码执行的高危漏洞,该漏洞由lgtm.com的安全研究员汇报,漏洞编号为C ...