記憶化搜尋 JZOJ P3767 路徑

2021-08-15 08:12:34 字數 2118 閱讀 7434

description

在乙個n個節點的無向圖(沒有自環、重邊)上,每個點都有乙個符號,可能是數字,也可能是加號、減號、乘號、除號、小括號。你要在這個圖上數一數,有多少種走恰好k個節點的方法,使得路過的符號串起來能夠得到乙個算數表示式 算數表示式。路徑的起點和終點可以任意選擇。

所謂算數表示式 算數表示式,就是由運算子連線起來的一系列數字。括號可以插入在表示式中以表明運算順序。

注意,你要處理各種情況,比如數字不能有多餘的前導0,減號只有前面沒有運算子或數字的時候才可以當成負號,括號可以任意新增(但不能有空括號),0可以做除數(我們只考慮文法而不考慮語意),加號不能當正號。

例如,下面的是合法的表示式:

-0/ 0

((0)+(((2*3+4)+(-5)+7))+(-(2*3)*6))

而下面的不是合法的表示式:

001+0

1+2(2)

3+-3

–1+1

input

第一行三個整數n,m,k,表示點的數量,邊的數量和走的節點數。

第二行乙個字串,表示每個點的符號。

接下來m行,每行兩個數,表示一條邊連的兩個點的編號。

output

輸出一行乙個整數,表示走的方法數。這個數可能比較大,你只需要輸出它模1000000007的餘數即可。

sample input

6 10 3

)(1*+0

1 21 3

1 42 3

3 42 5

3 53 6

4 65 6

sample output

data constraint

對於40%的資料,n,m,k≤10

對於100%的資料,1≤n≤20,0≤m≤n×(n-1)/ 2,0≤k≤30

hint

【樣例解釋】

一共有10條路徑,構成的表示式依次是101, (1), 1+1, 1+0, 1*1, 1*0, 0+0, 0+1, 0*0, 0*1

這題資料不大,可以考慮一下dp

(然而**實現能力太弱,打了一半發現打不下去了,果斷清空,打記憶化搜尋)

設f[i][j][k][0/1]為從第i個開始到第j個,'('的數量-')'的數量為k,01為有沒有前導0

然後就可以分類討論了(i為列舉的,x為當前)

①如果i為數字

⑴x也為數字 +=dfs(i,dep+1,c,0);

⑵x為運算子或左括號 +=dfs(i,dep+1,c,s[i]=='0')

②如果i為括號

⑴如果i為左括號而且x為左括號或運算子 +=dfs(i,dep+1,c+1,0)

⑵如果i為右括號而且c>0而且x為數字或右括號 +=dfs(i,dep+1,c-1,0)

③如果i為運算子

⑴如果x為數字 +=dfs(i,dep+1,c,0);

⑵如果x為右括號或x為左括號而且i為負號(因為+號不能代表正數) +=dfs(i,dep+1,c,0)

#include

#include

#include

#define mo 1000000007

using

namespace

std;

__attribute__((optimize("-o3")))

intmap[50][50],ans,n,m,num,f[25][35][35][2];

char s[30];

bool check(int x)

bool pd(int x)

int dfs(int x,int k,int c,int t)

else

if (check(x)||s[x]=='(') (mx+=dfs(i,k+1,c,s[i]=='0'))%=mo;

}else

if (s[i]=='('||s[i]==')')

else

}f[x][k][c][t]=mx;

return mx;

}int main()

memset(f,-1,sizeof(f));

for (int i=1;i<=n;i++)

printf("%d\n",ans);

}

記憶化搜尋

演算法上依然是搜尋的流程,但是搜尋到的一些解用 動態規劃 的那種思想和模式作一些儲存。一般說來,動態規劃總要遍歷所有的狀態,而搜尋可以排除一些無效狀態。更重要的是搜尋還可以剪枝,可能剪去大量不必要的狀態,因此在空間開銷上往往比動態規劃要低很多。記憶化演算法在求解的時候還是按著自頂向下的順序,但是每求...

記憶化搜尋

記憶化搜尋 演算法上依然是搜尋的流程,但是搜尋到的一些解用動態規劃的那種思想和模式作一些儲存。記憶化演算法在求解的時候還是按著自頂向下的順序,但是每求解乙個狀態,就將它的解儲存下來,以後再次遇到這個狀態的時候,就不必重新求解了。例1.題目描述 給從左至右排好隊的小朋友們分糖果,要求 1.每個小朋友都...

記憶化搜尋

原文 感謝作者。一.動態規劃 動態規劃 dynamic programming 與 分治思想 有些相似,都是利用將問題分 為子問題,並通過合併子問題的解來獲得整個問題的解。於 分治 的不同之處在 於,對於乙個相同的子問題動態規劃演算法不會計算第二次,其實現原理是將每乙個計算過的子問題的值儲存在乙個表...