Codeforces 379D - New Year Letter
原题地址:http://codeforces.com/contest/379/problem/D
题目大意:给出一种生成字符串的方法 s[k] = s[k - 2] + s[k - 1],其中加法意为将左右两个字符串直接相连,要求构造两个长度分别为n、m的字串s[1]、s[2],使得按照这种方法得出的s[k]中恰好含有 x 个 “AC”(意思大家都懂的……)如果无解,输出“Happy new year!”
数据范围:3 ≤ k ≤ 50; 0 ≤ x ≤ 109; 1 ≤ n, m ≤ 100
题目分析:
这道题算法很明确。
先将问题反过来思考:假设给定两个串s[1]、s[2],用题目中的方法生成s[k],求出s[k]含有几个“AC”,显然可以用动态规划解决
定义f[k]表示第k个串中含有“AC”的个数,Suf[k]为第 k 个串的结尾字母,Pre[k]为第k个串的开头字母,三个数组的1、2两位都是已知的
显然可以得到动态规划方程 f[k] = f[k - 2] + f[k - 1] + (Suf[k - 2] == 'A') && (Pre[k - 1] == 'C'); Suf[k] = Suf[k - 1]; Pre[k] = Pre[k - 2]
然后搞一搞就得到答案了。那么我们回归这道题,发现可以通过枚举f[1]、f[2]、Suf[1]、Suf[2]、Pre[1]、Pre[2]来DP计算所有可能的f[k],如果找到一组f[1]、f[2]、Suf[1]、Suf[2]、Pre[1]、Pre[2]使得f[k] == x,就按照它们构造两个字符串输出就好了
复杂度分析:每次枚举Pre[1]等等都是三种情况(是A、是C、不是A也不是C),一共枚举4轮,枚举f[1]时不可能超过二分之n,枚举f[2]时也同理,所以枚举的总复杂度是O(3 * 3 * (m / 2) * 3 * 3 * (n / 2))大约为202500,每次DP都是线性的所以复杂度是O(k)所以总复杂度可以约归为O(nmk)大概在10^7左右勉强不会超时。
剩下的就是细节了,这道题一大堆特殊情况需要判断(比如n , m <= 2啦什么的),详见代码~
//date 20140120
#include <cstdio>
#include <cstring> inline int min(int a, int b){return a < b ? a : b;}
inline int max(int a, int b){return a > b ? a : b;} int k, n, m;
long long x;
long long f[];
int suf[], pre[]; void dp(int w)
{
if(w <= )return;
if(f[w - ] == -)dp(w - );
if(f[w - ] == -)dp(w - );
f[w] = f[w - ] + f[w - ] + ((suf[w - ] == ) && (pre[w - ] == ));
suf[w] = suf[w - ]; pre[w] = pre[w - ];
} inline void output(int S1, int S2, int P1, int P2, int i, int j)
{
// printf("%d %d %d %d %d %d\n", S1, P1, i, S2, P2, j);
char ans1[], ans2[];
memset(ans1, , sizeof ans1);
memset(ans2, , sizeof ans2);
ans1[] = P1 + 'A' - ;
ans2[] = P2 + 'A' - ;
ans1[n] = S1 + 'A' - ;
ans2[m] = S2 + 'A' - ;
// printf("%s\n%s\n", ans1 + 1, ans2 + 1); int a1 = , a2 = ;
if(i > && ans1[] == 'A')
{
ans1[] = 'C';a1 = ;
for(int q = ; q < i; ++q){ans1[q * + ] = 'A'; ans1[q * + ] = 'C'; a1 = q * + ;}
for(int q = a1; q < n; ++q)ans1[q] = 'B';
}
else
{
a1 = ;
for(int q = ; q <= i; ++q){ans1[q * ] = 'A'; ans1[q * + ] = 'C'; a1 = q * + ;}
for(int q = a1; q < n; ++q)ans1[q] = 'B';
}
if(j > && ans2[] == 'A')
{
ans2[] = 'C'; a2 = ;
for(int q = ; q < j; ++q){ans2[q * + ] = 'A'; ans2[q * + ] = 'C'; a2 = q * + ;}
for(int q = a2; q < m; ++q)ans2[q] = 'B';
}
else
{
a2 = ;
for(int q = ; q <= j; ++q){ans2[q * ] = 'A'; ans2[q * + ] = 'C'; a2 = q * + ;}
for(int q = a2; q < m; ++q)ans2[q] = 'B';
}
printf("%s\n%s\n", ans1 + , ans2 + );
} int main()
{
// freopen("d.in", "r", stdin); scanf("%d%I64d%d%d", &k, &x, &n, &m); for(int P1 = ; P1 <= ; ++P1)
for(int S1 = ; S1 <= ; ++S1)
for(int P2 = ; P2 <= ; ++P2)
for(int S2 = ; S2 <= ; ++S2)
{
if(n == && S1 != P1)continue;
if(m == && S2 != P2)continue;
int uLim1 = , uLim2 = , dLim1 = , dLim2 = ;
uLim1 = max(n / - , ); if((n >= ) && ((S1 == && P1 == ) || ((n & ) && (S1 == || P1 == ))))++uLim1;
uLim2 = max(m / - , ); if((m >= ) && ((S2 == && P2 == ) || ((m & ) && (S2 == || P2 == ))))++uLim2;
if(n == && S1 == && P1 == )dLim1 = uLim1 = ;
if(m == && S2 == && P2 == )dLim2 = uLim2 = ;
// printf("%d %d %d %d\n", dLim1, uLim1, dLim2, uLim2);
for(int i = dLim1; i <= uLim1; ++i)
for(int j = dLim2; j <= uLim2; ++j)
{
memset(suf, , sizeof suf);
memset(pre, , sizeof pre);
suf[] = S1; suf[] = S2;
pre[] = P1; pre[] = P2;
memset(f, 0xFF, sizeof f);
f[] = i; f[] = j;
dp(k);
// printf("%d %d %d %d %d %d %d\n", P1, S1, P2, S2, i, j, f[k]);
if(f[k] == x){output(S1, S2, P1, P2, i, j); return ;}
}
} printf("Happy new year!\n");
return ;
}
小注:希望通过这道题能给我和大家带来更多的新年AC~
Codeforces 379D - New Year Letter的更多相关文章
- codeforces Good Bye 2013 379D New Year Letter
题目链接:http://codeforces.com/problemset/problem/379/D [题目大意] 告诉你初始字符串S1.S2的长度和递推次数k, 使用类似斐波纳契数列的字符串合并的 ...
- 【codeforces 379D】New Year Letter
[题目链接]:http://codeforces.com/contest/379/problem/D [题意] 让你构造出两个长度分别为n和m的字符串s[1]和s[2] 然后按照连接的规则,顺序连接s ...
- CodeForces 379D 暴力 枚举
D. New Year Letter time limit per test 1 second memory limit per test 256 megabytes input standard i ...
- Codeforces Round #284 (Div. 2)A B C 模拟 数学
A. Watching a movie time limit per test 1 second memory limit per test 256 megabytes input standard ...
- cf499B-Lecture 【map】
http://codeforces.com/problemset/problem/499/B B. Lecture You have a new professor of graph theo ...
- 物联网学生科协第三届H-star现场编程比赛
问题 A: 剪纸片 时间限制: 1 Sec 内存限制: 128 MB 题目描写叙述 这是一道简单的题目,假如你身边有一张纸.一把剪刀.在H-star的比赛现场,你会这么做: 1. 将这张纸剪成两片(平 ...
- Codeforces Round #116 (Div. 2, ACM-ICPC Rules) C. Letter 暴力
C. Letter Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/180/problem/C D ...
- Codeforces Beta Round #14 (Div. 2) A. Letter 水题
A. Letter 题目连接: http://www.codeforces.com/contest/14/problem/A Description A boy Bob likes to draw. ...
- CodeForces 379 D. New Year Letter
枚举开头结尾的字母,枚举ac的个数,总AC个数就是两个Fibonacci数列的和..... D. New Year Letter time limit per test 1 second memory ...
随机推荐
- PHP 中的BOM BUG
对于PHP,一个小小让我不敢置信的事情很多,包括引用变量哪么迟钝,普通变量哪么牛B我己经很意外,甚至现在竟然出现了BOM头的BUG. 在PHP中,会引用很多小文件,include或require,哪么 ...
- Mongo:将查询结果转换为自定义类
1.自定义类 public class MyClass { public string Name { get; set; } public int Corners { get; set; } } 2. ...
- Nginx 301重定向域名
为何要使用301重定向 在网站建设中需要网页重定向的情况很多:如网页目录结构变动,网页重命名.网页的扩展名改变.网站域名改变等.如果不做重定向,用户的收藏和搜索引擎数据库中的旧地址只能让访客得到一个4 ...
- CSS属性--过渡(transtion)
首先介绍一下transition的属性取值: transition-property : 主要设置对象中的参与过渡的属性,包括(border-color,background-color,color) ...
- 关于make: *** No rule to make target `clean'. Stop.的解决
在重新编译makefile工程文件时需要用到 #make clean 命令, 但是最近工程使用make clean的时候总是提示: make: *** No rule to make target ` ...
- Unity3D 问题流水总结
一.error CS1612:Cannot modify a value type return value of `UnityEngine.SliderJoint2D.limits'. Consid ...
- Unity3D脚本中文系列教程(十)
http://dong2008hong.blog.163.com/blog/static/4696882720140312627682/?suggestedreading&wumii Unit ...
- Cent Os 常用操作
开放端口 编辑iptables文件(/etc/sysconfig/iptables) -A INPUT -m state --state NEW -m tcp -p tcp --dport xx端口号 ...
- 关于navicat连接oracle 报 ORA-12737 set CHS16GBK错误的解决方案
[转]关于navicat连接oracle 报 ORA-12737 set CHS16GBK错误的解决方案 昨天下载安装了navicat 9.0 Premium(高级英文版),连接mysql正常,看到他 ...
- Zabbix 安装及微信短信提醒
Zabbix简介 Zabbix 近几年得到了各大互联网公司的认可,当然第一点归功与它强大的监控功能,第二点免费开源也得到了广大用户的青睐.Zabbix 能将操作系统中的绝大部分指标进行监控,比如(CP ...