re: 2-SAT 小结 _Yuan 2011-08-07 02:41
@QQ438846876
先正后反一样的吧
re: 几道数位统计 用记忆化搜索写 很方便 _Yuan 2011-07-15 20:15
@JayGuy
多谢指出呀
pre<0时应该不行的
re: poj 2057 _Yuan 2011-07-04 01:20
@[SCUT]iNowForDream
我很懒的。。
厄。。
之前考完试,随便做了一道而已。。
@dslztx
您试试这个数据,答案是2
2 1
0 1
0 1
1 2
@applepi
多谢指出错误
貌似 beg=max(0,pos-N);
改为 beg=max(i,pos-N);
可以过
@dslztx
DFS(v,c-weight[v]);//修改上限
这里v可能很大,但是它是叶子
题目说了非叶子的编号直到500
但叶子可以到很大,自然数组越界了
所以判断下是否是叶子,叶子的话,就不用dfs了
@Yular
我以前的做法比较土了...
这种类型的,貌似直接用priority_queue更直接
呵呵...
re: hdu 3570 ★★★ _Yuan 2010-11-06 19:09
@superbin
厄....我的方法比较笨,建立自动机搞的
/*
题意:一只猴子要打长度为m的字,他会打n种字母,每种概率p[i]
问最后打出包含目标串的概率
对目标串建立AC自动机
然后dp[len,j]表示长度为len,在节点j的概率
初始dp[0,1] = 1.0
然后枚举下一步打的字母转移即可了
最后答案就是 1 - 不包含目标串的概率
为了不包含目标串,算的时候那个危险节点不能走
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
#include <vector>
#include <algorithm>
using namespace std;
const int MAXN = 100000;
const double EPS = 1e-5;
double dp[2][MAXN];
double p[26];
struct Node
{
Node *ch[26] , *next;
int match , id;
}nodes[MAXN] , *Trie,*SuperRoot;
int alloc;
Node *newNode()
{
memset(&nodes[alloc] , 0 , sizeof(nodes[0]));
nodes[alloc].id = alloc;
return &nodes[alloc++];
}
void insert(Node *root ,char *s)
{
if(*s==0)root->match = 1;
else
{
if(root->ch[*s-'a'] == 0)root->ch[*s-'a'] = newNode();
insert(root->ch[*s-'a'] , s+1);
}
}
void buildTrie()
{
for(int i = 0 ; i < 26 ;i++)SuperRoot->ch[i] = Trie;
Trie->next = SuperRoot;
queue<Node*>Q;
Q.push(Trie);
while(!Q.empty())
{
Node *p = Q.front() ; Q.pop();
for(int i = 0 ; i < 26 ; i++)
{
if(p->ch[i])
{
p->ch[i]->next = p->next->ch[i];
Q.push(p->ch[i]);
}
else p->ch[i] = p->next->ch[i];
}
}
}
char str[1010];
int main()
{
// freopen("in","r",stdin);
// freopen("out","w",stdout);
int n ,m;
while( scanf("%d%d",&n,&m) , n||m)
{
memset(p,0,sizeof(p));
for(int i = 0 ; i< n; i++)
{
char ch;
scanf(" %c",&ch);
scanf("%lf",&p[ch-'a']);
}
scanf("%s",str);
alloc = 0;
SuperRoot = newNode();
Trie = newNode();
insert(Trie,str);
buildTrie();
int pre = 0 , next = 1;
for(int j = 0 ; j < alloc;j++)
dp[pre][j] = 0.0;
dp[pre][1] = 1.0;
for(int i = 0 ; i < m ; i++)
{
for(int j= 0 ; j < alloc;j++)
{
dp[next][j] = 0.0;
// printf("%d %.2f\n",j,dp[pre][j]);
}
//puts("");
for(int j = 1 ; j < alloc-1 ; j++)//目标串在alloc-1节点处
{
if( dp[pre][j] < EPS ) continue;
for(int k = 0 ; k < 26 ; k++)
{
int id = nodes[j].ch[k]->id;
dp[next][id] += dp[pre][j]*p[k];
}
}
swap(pre,next);
}
double ans = 1.0;
for(int j = 1 ; j < alloc-1 ; j++)//用1-所有不包含目标串的概率
ans -= dp[pre][j];
printf("%.2f%%\n",ans*100);
}
return 0;
}
你的高斯消元好快
呵呵
我自己写的。。。TLE。。。哎
@superbin
本来[k,i]是由[k-1,j]过来的,这样子就要枚举j了
发现[k,i-1]也是由[k-1,j']过来的,这样子[k,i]也能由[k,i-1]过来,这样子就不用枚举那个j了
对比
[k,i-1] = rev(j+1,i-1) + [k-1,j] k-1<=j<=i-2
[k,i] = rev(j+1,i) + [k-1,j] k-1<=j<=i-1
发现这里[k,i] [k,i-1]不同的地方就是那个j,对于i需要再比较多一次j = i-1
所以[k,i] 就可以用 [k,i-1],[k-1,i-1](这就是多一次的比较了)来更新了
re: hdu 3660 _Yuan 2010-10-03 10:49
@Mercy
不客气
re: hdu 3660 _Yuan 2010-10-03 10:34
@Mercy
我那个dfs里有加一句
if(dist[u]>R){dp[u] = 0;return;}
如果还没到叶子就已经不行了就不走了
如果一直都满足条件的话就会走到叶子了
re: hdu 3660 _Yuan 2010-10-02 22:58
@Mercy
恩,是树形dp
dp[v]表示以v为根的子树获得的最优值
由于有L,R
这个值需要 L<=dist[v]+dp[v]<=R即在决策时找一些合法的点来更新u)
dist[0]=0,那么dp[0]就是答案了
re: hdu 3660 _Yuan 2010-10-02 18:03
@552734199
多谢指出
是两条语句的顺序问题
改为这样
dist[v] = dist[u] + w;
dfs(v,!who);
就可以了吧?
re: hdu 3660 _Yuan 2010-10-01 18:21
@aaa
这题G++会超时 C++可以过
感觉Hdu卡常数了
O(n)的算法
re: nm的棋盘 放炮 的方案数 ★★★ _Yuan 2010-08-30 15:49
@jince
这个倒没有,之前训练时的题目,是一个OI的题,但是我搜不到...
不过有标程...
re: There is a tree 树DP _Yuan 2010-08-06 10:43
@sleepiforest
呵呵,本来就是嘛。。。
re: There is a tree 树DP _Yuan 2010-08-05 23:58
@Sirius
您明天又要爆发了
@possessor WC
厄。。。我不是大牛。。呵呵,我只是小菜。。。