re: 2-SAT 小結(jié) _Yuan 2011-08-07 02:41
@QQ438846876
先正后反一樣的吧
@JayGuy
多謝指出呀
pre<0時應該不行的
re: poj 2057 _Yuan 2011-07-04 01:20
@[SCUT]iNowForDream
我很懶的。。
厄。。
之前考完試,隨便做了一道而已。。
@dslztx
您試試這個數(shù)據(jù),答案是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
但葉子可以到很大,自然數(shù)組越界了
所以判斷下是否是葉子,葉子的話,就不用dfs了
@Yular
我以前的做法比較土了...
這種類型的,貌似直接用priority_queue更直接
呵呵...
re: hdu 3570 ★★★ _Yuan 2010-11-06 19:09
@superbin
厄....我的方法比較笨,建立自動機搞的
/*
題意:一只猴子要打長度為m的字,他會打n種字母,每種概率p[i]
問最后打出包含目標串的概率
對目標串建立AC自動機
然后dp[len,j]表示長度為len,在節(jié)點j的概率
初始dp[0,1] = 1.0
然后枚舉下一步打的字母轉(zhuǎn)移即可了
最后答案就是 1 - 不包含目標串的概率
為了不包含目標串,算的時候那個危險節(jié)點不能走
*/
#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節(jié)點處
{
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了
發(fā)現(xiàn)[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
發(fā)現(xiàn)這里[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;}
如果還沒到葉子就已經(jīng)不行了就不走了
如果一直都滿足條件的話就會走到葉子了
re: hdu 3660 _Yuan 2010-10-02 22:58
@Mercy
恩,是樹形dp
dp[v]表示以v為根的子樹獲得的最優(yōu)值
由于有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卡常數(shù)了
O(n)的算法
@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
您明天又要爆發(fā)了
@possessor WC
厄。。。我不是大牛。。呵呵,我只是小菜。。。