D - We Like AGC


Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 400400 points

Problem Statement

You are given an integer NN. Find the number of strings of length NN that satisfy the following conditions, modulo 109+7109+7:

  • The string does not contain characters other than ACG and T.
  • The string does not contain AGC as a substring.
  • The condition above cannot be violated by swapping two adjacent characters once.

Notes

A substring of a string TT is a string obtained by removing zero or more characters from the beginning and the end of TT.

For example, the substrings of ATCODER include TCOATCODERATCODER and  (the empty string), but not AC.

Constraints

  • 3≤N≤1003≤N≤100

Input

Input is given from Standard Input in the following format:

NN

Output

Print the number of strings of length NN that satisfy the following conditions, modulo 109+7109+7.


Sample Input 1 Copy

Copy
3

Sample Output 1 Copy

Copy
61

There are 43=6443=64 strings of length 33 that do not contain characters other than ACG and T. Among them, only AGCACG and GAC violate the condition, so the answer is 64−3=6164−3=61.


Sample Input 2 Copy

Copy
4

Sample Output 2 Copy

Copy
230

Sample Input 3 Copy

Copy
100

Sample Output 3 Copy

Copy
388130742

Be sure to print the number of strings modulo 109+7109+7.

题意:

给你一个数字N,N的范围是3~100

让你求出有多少种可能的字符串,使之只包括这四种字符 ACG and T.

并且字符串不含有“AGC”这个子串,并且仅交换一次相邻的字符也不含有“AGC”这个子串。

思路:

我们根据第一个样例就可以看出N=3的所有情况。

因为我们考虑的是DP的写法,先思考如何定义状态,

我们通过思考可以知道我们从N=3转到N=4的状态的时候,我们要考虑整个字符串的后3个字符才可以确定最后一位能不能加上我们在转移的字符,

那么我们不妨在定义状态的时候就把整个字符串的后3位字符都存下来。

所以我们定义状态如下:

DP[ len ][i] [ j ] [ k ] = 长度为len的字符串中,后三位字符串依次是ijk的字符串有多少种。

这里因为只有四种字母,我们不妨给四个字符进行用数码编号表示,以此来简化我们的程序编写;

我们按照字典序把{'A','C','G','T'}; 编为 0 1 2 3.

那么我们现在从N=4开始考虑,

我们知道以下几种情况是不能满足条件的

后三位是  我们不能接上

*AG  C

*AC  G

*GA  C

A*G  C

AG*  C

我们只需要在转移的时候,把这5种会产生不符合条件的字符串给删除掉(即不计入计数)

就可以顺利的推出答案了。

具体转移的细节见代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#define ALL(x) (x).begin(), (x).end()
#define rt return
#define dll(x) scanf("%I64d",&x)
#define xll(x) printf("%I64d\n",x)
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define gg(x) getInt(&x)
#define db(x) cout<<"== [ "<<x<<" ] =="<<endl;
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
ll powmod(ll a,ll b,ll MOD){ll ans=;while(b){if(b%)ans=ans*a%MOD;a=a*a%MOD;b/=;}return ans;}
inline void getInt(int* p);
const int maxn=;
const int inf=0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
int n;
const ll mod = 1e9+7ll;
ll dp[][][][];
char c[]={'A','C','G','T'};
int main()
{
//freopen("D:\\common_text\\code_stream\\in.txt","r",stdin);
//freopen("D:\\common_text\\code_stream\\out.txt","w",stdout);
// gbtb*/
cin>>n;
string temp="";
int num=;
// repd(i,0,3)
// {
// temp[0]=c[i];
// repd(j,0,3)
// {
// temp[1]=c[j];
// repd(k,0,3)
// {
// temp[2]=c[k];
// cout<<num++<<" ";
// cout<<temp<<endl;
// }
// }
// }
// char c[6]={'A','C','G','T'};
repd(i,,)
{
repd(j,,)
{
repd(k,,)
{
dp[][i][j][k]=;
}
}
}
dp[][][][]=;
dp[][][][]=;
dp[][][][]=;
ll cnt=0ll;
repd(len,,n)
{
repd(i,,)
{
repd(j,,)
{
repd(k,,)
{
cnt=0ll; repd(ii,,)
{
repd(jj,,)
{
repd(kk,,)
{
//{'A','C','G','T'};
if(jj==i&&kk==j)
{
if(k==&&kk==&&jj==)
{ }else if(k==&&kk==&&jj==)
{ }else if(k==&&kk==&&jj==)
{ }else if(k==&&kk==&&ii==)
{ }else if(k==&&jj==&&ii==)
{ }else
{
cnt+=dp[len-][ii][jj][kk];
cnt=(cnt+mod)%mod;
}
} }
}
}
cnt=(cnt+mod)%mod;
dp[len][i][j][k]=cnt;
// printf("%d %d %d %lld\n",i,j,k,cnt);
}
}
}
}
ll ans=0ll;
repd(i,,)
{
repd(j,,)
{
repd(k,,)
{
ans+=dp[n][i][j][k];
ans=(ans+mod)%mod;
} }
}
cout<<ans<<endl;
return ;
} inline void getInt(int* p) {
char ch;
do {
ch = getchar();
} while (ch == ' ' || ch == '\n');
if (ch == '-') {
*p = -(getchar() - '');
while ((ch = getchar()) >= '' && ch <= '') {
*p = *p * - ch + '';
}
}
else {
*p = ch - '';
while ((ch = getchar()) >= '' && ch <= '') {
*p = *p * + ch - '';
}
}
}

AtCoder Beginner Contest 122 D - We Like AGC (DP)的更多相关文章

  1. AtCoder Beginner Contest 122 D - We Like AGC(DP)

    题目链接 思路自西瓜and大佬博客:https://www.cnblogs.com/henry-1202/p/10590327.html#_label3 数据范围小 可直接dp f[i][j][a][ ...

  2. Atcoder Grand Contest 030 F - Permutation and Minimum(DP)

    洛谷题面传送门 & Atcoder 题面传送门 12 天以前做的题了,到现在才补/yun 做了一晚上+一早上终于 AC 了,写篇题解纪念一下 首先考虑如果全是 \(-1\)​ 怎么处理.由于我 ...

  3. Atcoder Grand Contest 024 E - Sequence Growing Hard(dp+思维)

    题目传送门 典型的 Atcoder 风格的计数 dp. 题目可以转化为每次在序列中插入一个 \([1,k]\) 的数,共操作 \(n\) 次,满足后一个序列的字典序严格大于前一个序列,问有多少种操作序 ...

  4. AtCoder Beginner Contest 122 解题报告

    手速选手成功混进rated only里面的前30名,但是总排名就到110+了... A - Double Helix #include <bits/stdc++.h> #define ll ...

  5. [题解] Atcoder Beginner Contest ABC 265 Ex No-capture Lance Game DP,二维FFT

    题目 首先明确先手的棋子是往左走的,将其称为棋子1:后手的棋子是往右走的,将其称为棋子2. 如果有一些行满足1在2右边,也就是面对面,那其实就是一个nim,每一行都是一堆石子,数量是两个棋子之间的空格 ...

  6. Atcoder Grand Contest 010 C - Cleaning 树贪心(伪)

    C - Cleaning 题目连接: http://agc010.contest.atcoder.jp/tasks/agc010_c Description There is a tree with ...

  7. Atcoder Grand Contest 001 D - Arrays and Palindrome(构造)

    Atcoder 题面传送门 洛谷题面传送门 又是道思维题,又是道把我搞自闭的题. 首先考虑对于固定的 \(a_1,a_2,\dots,a_n;b_1,b_2,\dots,b_m\) 怎样判定是否合法, ...

  8. Atcoder Regular Contest 096 C - Everything on It(组合数学)

    Atcoder 题面传送门 & 洛谷题面传送门 简单题,由于这场 arc 的 F 是 jxd 作业而我不会做,所以只好来把这场的 E 水掉了. 我们记 \(f(i)\) 为钦定 \(i\) 个 ...

  9. Atcoder Grand Contest 034 F - RNG and XOR(FWT)

    Atcoder 题面传送门 & 洛谷题面传送门 tsc 考试前 A 的题了,结果到现在才写这篇题解--为了 2mol 我已经一周没碰键盘了,现在 2mol 结束算是可以短暂的春天 短暂地卷一会 ...

随机推荐

  1. shell的case用法

    今天给大家简单介绍一下结构条件语句的用法,实际上就是规范的多分支if语句,如下: case语法: case "字符串变量" in 值1)指令1... ;; 值2)指令2... ;; ...

  2. Python - 判断list是否为空

    Python中判断list是否为空有以下两种方式: 方式一: list_temp = [] if len(list_temp): # 存在值即为真 else: # list_temp是空的 方式二: ...

  3. 实现Github和Coding仓库等Git服务托管更新

    如何使Github.Coding.Gitee 码云 同时发布更新,多个不同Git服务器之间同时管理部署发布提交 缘由 因为在Github上托管的静态页面访问加载速度较为缓慢,故想在Coding上再建一 ...

  4. C# -- 内插字符串的使用

    C# -- 内插字符串的使用 (1) 字符串文本以 $ 字符开头,后接左双引号字符. $ 符号和引号字符之间不能有空格.(2) 内插字符串表达式的结果可以是任何数据类型.(3) 可通过在内插表达式后接 ...

  5. LeetCode算法题-Range Sum Query Immutable(Java实现)

    这是悦乐书的第204次更新,第214篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第70题(顺位题号是303).给定整数数组nums,找到索引i和j(i≤j)之间的元素之 ...

  6. vonic单页面应用

    Vonic—基于Vue.js和ionic样式的移动端UI框架 先放上源码和demo地址: 标签演示:  https://wangdahoo.github.io/vonic/docs/       源码 ...

  7. 学习Ant Design Pro的一点心得

    1.控制反转(Inversion of Control)是一种「思想」,依赖注入(Dependency Injection)则是这一思想的一种具体「实现方式」 2.react 要注意全局 id相同 3 ...

  8. java锁的种类以及辨析(一):自旋锁

    作者:山鸡 锁作为并发共享数据,保证一致性的工具,在JAVA平台有多种实现(如 synchronized 和 ReentrantLock等等 ) .这些已经写好提供的锁为我们开发提供了便利,但是锁的具 ...

  9. P1897 电梯里的爱情

    简单模拟: 没什么好说的,因为范围比较水,所以直接按题意直接模拟1就好 #include<iostream> using namespace std; #define ll long lo ...

  10. hyperledge环境安装

    1.安装环境 1)本机安装 前提是已经安装好了docker\docker-compose\go,相应的内容可见 docker-1-环境安装及例子实践 docker官方文档学习-1-Docker for ...