Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 7414 Accepted Submission(s): 3064
医学界发现的新病毒因其蔓延速度和Internet上传播的”红色病毒”不相上下,被称为”红色病毒”,经研究发现,该病毒及其变种的DNA的一条单链中,胞嘧啶,腺嘧啶均是成对出现的。
现在有一长度为N的字符串,满足一下条件:
(1) 字符串仅由A,B,C,D四个字母组成;
(2) A出现偶数次(也可以不出现);
(3) C出现偶数次(也可以不出现);
计算满足条件的字符串个数.
当N=2时,所有满足条件的字符串有如下6个:BB,BD,DB,DD,AA,CC.
由于这个数据肯能非常庞大,你只要给出最后两位数字即可.
每组输入的第一行是一个整数T,表示测试实例的个数,下面是T行数据,每行一个整数N(1<=N<2^64),当T=0时结束.
对于每个测试实例,输出字符串个数的最后两位,每组输出后跟一个空行.
4
1
4
20
11
3
14
24
6
0
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
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
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 second
const 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;
}