您的位置:首页 > 编程语言

DP 看别人的代码涨眼界

2017-04-02 23:03 106 查看


hihoCoder 编程练习赛10 缺勤记录II

描述

小Hi的算法课老师每次上课都会统计小Hi的出勤记录。迟到会被记录一个L,缺席会被记录一个A,按时上课会被记录一个O。

一学期结束,小Hi的出勤记录可以看成是一个只包含LAO的字符串,例如"OOOOLOOOLALLO……"。

如果小Hi整学期缺席不超过1次,并且没有连续3次迟到,小Hi的出勤记录就算合格。  

现在给出字符串的长度N,小Hi想知道长度为N的出勤记录中,合格的记录总共有多少种。  

例如长度为3的合格出勤记录有19种:OOO OOL OOA OLO OAO LOO AOO OLL OLA OAL LOL LOA AOL LLO LAO ALO LLA LAL ALL。

输入

一个整数N(1 <= N <= 100000)。

输出

长度为N的合格记录总数。由于结果可能很大,你只需输出结果模109+7的余数。

样例输入
3


样例输出

19

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<bits/stdc++.h>
using namespace std;
const int Z = 1e9 + 7;
void gadd(int &a, int b) { a = (a + b) % Z; }
int n;
int f[100010][3][4], ans[100010];
int main()
{
f[0][0][0] = 1; //f[i][j][k]=1代表是合格的出勤表
for (int i = 0; i <= 100000; ++i)
{
for (int j = 0; j <= 1; ++j)
{
for (int k = 0; k <= 2; ++k)
if (f[i][j][k]) //只有合格的出勤表才有资格看下一步
{
gadd(ans[i], f[i][j][k]); //ans数组保存i个出勤记录时的合格数
//'A'
gadd(f[i + 1][j + 1][0], f[i][j][k]); //一个A就把连续迟到次数埋没成了0,缺勤次数加一。
//'L'
gadd(f[i + 1][j][k + 1], f[i][j][k]); //连续迟到的次数加一
//'O'
gadd(f[i + 1][j][0], f[i][j][k]); // 一个O就把连续迟到次数埋没成了0。
}
}
}
while (~scanf("%d", &n))
{
printf("%d\n", ans
);
}
return 0;
}
/*

【分析】
我们用f[i][j][k]表示已经考虑到了前i次出勤
缺勤次数为j,连续迟到次数为k,且合格的出勤方案数

*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: