意甲冠军:

给n快报,和m频率。

然后进入n字母出现的概率

然后给目标字符串str

然后问m概率倍的目标字符串是敲数量。

思维:

AC自己主动机+可能性dp简单的问题。

首先建立trie图,然后就是状态转移了

dp版本号:

dp三重循环变量次数,节点数,和字母数

代码:

#include"cstdlib"
#include"cstdio"
#include"cstring"
#include"cmath"
#include"queue"
#include"algorithm"
#include"iostream"
#include"map"
#include"string"
using namespace std;
int triecont;
double dp[1234][22];
struct trie
{
int mark,id;
trie *next[27],*fail;
trie()
{
mark=id=0;
memset(next,0,sizeof(next));
fail=NULL;
}
};
trie *root,*node[22];
void init(char *v)
{
trie *p=root;
for(int i=0;v[i];i++)
{
int tep=v[i]-'a';
if(p->next[tep]==NULL)
{
p->next[tep]=new trie();
node[triecont]=p->next[tep];
p->next[tep]->id=triecont++;
}
p=p->next[tep];
}
p->mark++;
}
void getac()
{
queue<trie*>q;
q.push(root);
while(!q.empty())
{
trie *p=q.front();
q.pop();
for(int i=0;i<26;i++)
{
if(p->next[i]==NULL)
{
if(p==root) p->next[i]=root;
else p->next[i]=p->fail->next[i];
}
else
{
if(p==root) p->next[i]->fail=root;
else p->next[i]->fail=p->fail->next[i];
q.push(p->next[i]);
}
}
}
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m),(n+m))
{
double gl[27];
memset(gl,0,sizeof(gl));
memset(node,0,sizeof(node));
while(n--)
{
char x[2];
double y;
scanf("%s%lf",x,&y);
gl[x[0]-'a']=y;
}
char fuck[27];
scanf("%s",fuck);
triecont=0;
root=new trie();
node[triecont]=root;
root->id=triecont++;
init(fuck);
getac();
memset(dp,0,sizeof(dp));
dp[0][0]=1;
for(int i=1;i<=m;i++)
{
for(int j=0;j<triecont-1;j++)
{
for(int k=0;k<26;k++)
{
trie *p=node[j]->next[k];
dp[i][p->id]+=dp[i-1][j]*gl[k];
}
}
}
double ans=0;
for(int i=0;i<=m;i++) ans+=dp[i][triecont-1]; printf("%.2f%%\n",ans*100);
}
return 0;
}

建立可达矩阵版本号:

注意到达目标状态 那么他之后的状态的概率就都是1了

然后用高速幂加速~

#include"cstdlib"
#include"cstdio"
#include"cstring"
#include"cmath"
#include"queue"
#include"algorithm"
#include"iostream"
using namespace std;
int triecont;
struct trie
{
int mark,id;
trie *next[27];
trie *fail;
trie()
{
mark=id=0;
memset(next,0,sizeof(next));
fail=NULL;
}
};
struct matrix
{
double mat[20][20];
};
trie *root;
void init(char *v)
{
trie *p=root;
for(int i=0; v[i]; i++)
{
int tep=v[i]-'a';
if(p->next[tep]==NULL)
{
p->next[tep]=new trie();
p->next[tep]->id=triecont++;
}
p=p->next[tep];
}
p->mark=1;
}
void getac()
{
queue<trie*>q;
q.push(root);
while(!q.empty())
{
trie *p;
p=q.front();
q.pop();
for(int i=0; i<26; i++)
{
if(p->next[i]==NULL)
{
if(p==root) p->next[i]=root;
else p->next[i]=p->fail->next[i];
}
else
{
if(p==root) p->next[i]->fail=root;
else p->next[i]->fail=p->fail->next[i];
q.push(p->next[i]);
}
}
}
}
matrix matmul(matrix a,matrix b,int n)
{
int i,j,k;
matrix c;
memset(c.mat,0,sizeof(c.mat));
for(i=0; i<n; i++)
{
for(j=0; j<n; j++)
{
for(k=0; k<n; k++)
{
c.mat[i][j]+=a.mat[i][k]*b.mat[k][j];
}
}
}
return c;
}
matrix matpow(matrix a,int k,int n)
{
matrix b;
int i;
memset(b.mat,0,sizeof(b.mat));
for(i=0; i<n; i++) b.mat[i][i]=1;
while(k)
{
if(k&1) b=matmul(a,b,n);
a=matmul(a,a,n);
k>>=1;
}
return b;
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m),(n+m))
{
double gl[27];
memset(gl,0,sizeof(gl));
while(n--)
{
char x[2];
double y;
scanf("%s%lf",x,&y);
gl[x[0]-'a']+=y;
}
triecont=0;
root=new trie();
root->id=triecont++;
char x[12];
scanf("%s",x);
init(x);
getac();
queue<trie*>q;
q.push(root);
int used[12];
memset(used,0,sizeof(used));
matrix a,ans;
memset(a.mat,0,sizeof(a.mat));
while(!q.empty())
{
trie *p=q.front();
q.pop();
if(used[p->id]) continue;
used[p->id]=1;
if(p->mark==1) //目标状态 兴许状态都是本身
{
a.mat[p->id][p->id]=1;
continue;
}
for(int i=0;i<26;i++)
{
if(used[p->next[i]->id]==0) q.push(p->next[i]);
a.mat[p->id][p->next[i]->id]+=gl[i];
}
}
/*for(int i=0;i<triecont;i++)
{
for(int j=0;j<triecont;j++) printf("%.2f ",a.mat[i][j]);
puts("");
}*/
ans=matpow(a,m,triecont);
printf("%.2f%%\n",ans.mat[0][triecont-1]*100);
}
return 0;
}

版权声明:本文博客原创文章,博客,未经同意,不得转载。

[AC自己主动机+可能性dp] hdu 3689 Infinite monkey theorem的更多相关文章

  1. HDU 3689 Infinite monkey theorem(DP+trie+自动机)(2010 Asia Hangzhou Regional Contest)

    Description Could you imaging a monkey writing computer programs? Surely monkeys are smart among ani ...

  2. HDU 3689 Infinite monkey theorem [KMP DP]

    Infinite monkey theorem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Oth ...

  3. hdu 3689 Infinite monkey theorem

    Infinite monkey theorem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/ ...

  4. [HDU 3689]Infinite monkey theorem (KMP+概率DP)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3689 黄老师说得对,题目只有做wa了才会有收获,才会有提高. 题意:一个猴子敲键盘,键盘上有n个键,猴 ...

  5. HDU 3689 Infinite monkey theorem ——(自动机+DP)

    这题由于是一个单词,其实直接kmp+dp也无妨.建立自动机当然也是可以的.设dp[i][j]表示匹配到第i个字母的时候,在单词中处于第j个位置的概率,因此最终的答案是dp[0~m][len],m是输入 ...

  6. ●HDU 3689 Infinite monkey theorem

    题链: http://acm.hdu.edu.cn/showproblem.php?pid=3689题解: KMP,概率dp (字符串都从1位置开始) 首先对模式串S建立next数组. 定义dp[i] ...

  7. ZOJ 3494 BCD Code (AC自己主动机 + 数位DP)

    题目链接:BCD Code 解析:n个病毒串.问给定区间上有多少个转换成BCD码后不包括病毒串的数. 很奇妙的题目. . 经典的 AC自己主动机 + 数位DP 的题目. 首先使用AC自己主动机,得到b ...

  8. POJ 3691 &amp; HDU 2457 DNA repair (AC自己主动机,DP)

    http://poj.org/problem?id=3691 http://acm.hdu.edu.cn/showproblem.php?pid=2457 DNA repair Time Limit: ...

  9. HDU 2825 Wireless Password (AC自己主动机,DP)

    pid=2825">http://acm.hdu.edu.cn/showproblem.php? pid=2825 Wireless Password Time Limit: 2000 ...

随机推荐

  1. POJ 1775 Sum of Factorials (ZOJ 2358)

    http://poj.org/problem?id=1775 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1334 题目大意: ...

  2. 【32.22%】【codeforces 602B】Approximating a Constant Range

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  3. Android 各个版本号WebView

    转载请注明出处   http://blog.csdn.net/typename/ powered by miechal zhao : miechalzhao@gmail.com 前言: 依据Googl ...

  4. ios开发瀑布流框架的封装

    一:瀑布流框架封装的实现思路:此瀑布流框架的封装仿照tableView的底层实现,1:每个cell的frame的设置都是找出每列的最大y值,比较每列的最大y值,将下一个cell放在最大y值最小的那一列 ...

  5. Android Notification如何显示表情?

    遇到这种分析用什么实现的,肯定要祭出大杀器Android Device Monitor(AS在Tools->Android)打开之后,选中连接的设备,然后点击小手机图标,即可导出UI层次图.咱们 ...

  6. Android 动态改变高度以及计算长度的EditText

    前段时间项目需求,需要做一个有限制长度的输入框并动态显示剩余文字,同时也要动态改变EditText的高度来增加用户体验.现整理出来与大家分享. 先来看看效果图 看了效果就分享一下布局 <Rela ...

  7. Java高级个人笔记(RandomStringUtils工具类)

    //产生5位长度的随机字符串,中文环境下是乱码 RandomStringUtils.random(5); //使用指定的字符生成5位长度的随机字符串 RandomStringUtils.random( ...

  8. [Compose] Isomorphisms and round trip data transformations

    What is Isomorphisms?We have a value x, then apply function 'to' and 'from' to value 'x', the result ...

  9. Android 用LinkedList实现队列

    队列 队列是一种特殊的线性表,它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作.进行插入操作的端称为队尾,进行删除操作的端称为队头.队列中没有元素时,称为空队列. 在 ...

  10. Java 类锁、对象锁、私有锁

    3.6 Java类锁.对象锁.私有锁.隐式锁 类锁和对象锁是否会冲突?对象锁和私有锁是否会冲突?通过实例来进行说明. 一.相关约定 为了明确后文的描述,先对本文涉及到的锁的相关定义作如下约定: 1. ...