[HDU 2065][dp]"红色病毒"问题
来源:互联网 发布:app文件上传java 接口 编辑:程序博客网 时间:2024/04/28 12:17
“红色病毒”问题
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 7414 Accepted Submission(s): 3064
Problem Description
医学界发现的新病毒因其蔓延速度和Internet上传播的”红色病毒”不相上下,被称为”红色病毒”,经研究发现,该病毒及其变种的DNA的一条单链中,胞嘧啶,腺嘧啶均是成对出现的。
现在有一长度为N的字符串,满足一下条件:
(1) 字符串仅由A,B,C,D四个字母组成;
(2) A出现偶数次(也可以不出现);
(3) C出现偶数次(也可以不出现);
计算满足条件的字符串个数.
当N=2时,所有满足条件的字符串有如下6个:BB,BD,DB,DD,AA,CC.
由于这个数据肯能非常庞大,你只要给出最后两位数字即可.
Input
每组输入的第一行是一个整数T,表示测试实例的个数,下面是T行数据,每行一个整数N(1<=N<2^64),当T=0时结束.
Output
对于每个测试实例,输出字符串个数的最后两位,每组输出后跟一个空行.
Sample Input
4
1
4
20
11
3
14
24
6
0
Sample Output
Case 1: 2
Case 2: 72
Case 3: 32
Case 4: 0
Case 1: 56
Case 2: 72
Case 3: 56
Author
Rabbit
Source
RPG专场练习赛
Recommend
lcy | We have carefully selected several similar problems for you: 2062 2069 2070 2073 2077
题解
这道题给我第一感觉就是dp,写题卡的过程中在网上找题解,没发现用dp写的。这里就贴一份吧。
首先我们把状态分一下:
一、A和C均为偶数,这就是要求的。
二、A为偶数、C为奇数。
三、A为偶数、C为奇数。
四、A为奇数、C为奇数。
下面直接用序号①②③④代替以上状态。
开一个dp数组,第一维记为串长,第二维则标记以上状态。
则①对应dp[i][0],②dp[i][1],③dp[i][2], ④dp[i][3]。
如dp[i][0]表示串长为i,A C数量均为偶数的数量。
初始状态dp[1][0] = 2, dp[1][1] = 1, dp[1][2] = 1, dp[1][3] = 0;
再推导递推式
串长为i的①串,可以由串长为i - 1的①串在后面添加 “B” 或 “D”, 或者串长为i - 1的②串+ “C”, 或串长为i - 1的③串 + “A”得到。
dp[i][0] = dp[i - 1][0] * 2 + dp[i - 1][1] + dp[i - 1][2];
串长为i的②串可以由串长为i-1的①串+ “C”,或②串 + “B” 或 “D”, 或④串 + “A”得到。
dp[i][1] = dp[i - 1][0] + dp[i - 1][1] * 2 + dp[i - 1][3];
③串和②串相似
dp[i][2] = dp[i - 1][0] + dp[i - 1][2] * 2 + dp[i - 1][3] ;
串长为i的④串可以由,串长为i - 1的②串 + “C” , ③串 + “A”,四串 + “B” 或 “D”。
dp[i][3] = dp[i - 1][1] + dp[i - 1][2] + dp[i - 1][3] * 2;
递推完成。不过本题还有一些小细节需要处理,题目要求的是末两位数字。如果直接在递推过程对100取模,会导致结果错误,我采取的做法是对推过程对10000取模,最后输出答案时再对100取模。
同时,由于n范围为2^64,直接递推到n肯定会超时。而最终答案只包含两位,所以其具有周期性是显而易见,打表出来,找下周期就可以解决了。
//#define LOCAL#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <vector>#include <map>#include <set>#include <stack>#include <queue>#include <iostream>#include <cstdlib>#include <algorithm>using namespace std;#define LL long long#define ll long long#define INF 0x3f3f3f3f#define maxn MAX_N#define MOD mod#define MMT(x,i) memset(x,i,sizeof(x))#define REP(i, n) for(int i = 0; i < n; i++)#define FOR(i, n) for(int i = 1; i <= n; i++)#define pb push_back#define mp make_pair#define X first#define Y secondconst LL MOD = 1e9 + 7;const double pi = acos(-1.0);const double E = exp(1);const double EPS = 1e-8;const int MAX_N = 1000010;int dp[10010][4];int main(){ #ifdef LOCAL freopen("in.txt", "r", stdin); freopen("out.txt", "w", stdout); #endif ios::sync_with_stdio(false); dp[0][0] = dp[0][1] = dp[0][2] = 1; dp[1][0] = 2, dp[1][1] = dp[1][2] = 1, dp[1][3] = 0; for(int i = 2; i <= 130; i++) { dp[i][0] = (dp[i - 1][0] * 2 + dp[i - 1][1] + dp[i - 1][2]) % 10000; dp[i][1] = (dp[i - 1][0] + dp[i - 1][1] * 2 + dp[i - 1][3]) % 10000; dp[i][2] = (dp[i - 1][0] + dp[i - 1][2] * 2 + dp[i - 1][3]) % 10000; dp[i][3] = (dp[i - 1][1] + dp[i - 1][2] + dp[i - 1][3] * 2) % 10000;// cout << i << " " << dp[i][0] % 100 << endl; } int T; while(cin >> T) { if(T == 0) break; for(int cas = 1; cas <= T; cas++) { long long n; cin >> n; int ans = 0; if(n <= 11) ans = dp[n][0]; else ans = dp[(n - 11) % (ll)20 + 11][0]; cout << "Case " << cas <<": " << ans % 100<< endl; } cout << endl; } return 0;}
- [HDU 2065][dp]"红色病毒"问题
- HDU 2065 "红色病毒"问题
- HDU 2065 "红色病毒"问题
- hdu 2065 "红色病毒"问题
- hdu 2065 "红色病毒"问题
- hdu 2065 "红色病毒"问题
- hdu 2065 "红色病毒"问题
- hdu 2065 "红色病毒"问题
- HDU-“红色病毒”问题
- HDU 2065 "红色病毒"问题 (快速幂)
- HDU's ACM 2065 "红色病毒"问题
- [HDU 2065] "红色病毒"问题 数论
- HDU 2065 "红色病毒"问题 【附递推】
- hdu 2065 红色病毒
- HDU 2065 红色病毒
- HDU 2065 红色病毒
- hdu 2065 "红色病毒"问题 (母函数)
- HDU 2065 "红色病毒"问题 (泰勒级数推导)
- python django环境配置
- L脚本语言 实用脚本文件
- 提高NetBeans的代码提示速度
- Spring boot源码分析-AnnotationConfigApplicationContext非web环境下的启动容器(2)
- Mac下安装MySQL-Python
- [HDU 2065][dp]"红色病毒"问题
- #时间#:datetime、time
- Annaconda 增加删除镜像 channel
- 常用终端命令
- 为nexus 5x编译android n固件
- 为什么mybatis的mapper没有实现类(原理探究)
- 一个c++单例模式例子中的c++语法?
- 谈客户如同谈恋爱,分析一下你为什么失恋?
- win7文件内容被意外修改后怎么恢复?