演算法訓練Sereja and Squares

2021-10-10 07:21:05 字數 2865 閱讀 1172

資源限制

時間限制:4.0s 記憶體限制:256.0mb

問題描述

輸入格式

第一行是乙個整數n,表示點的個數。

第二行是乙個長度為n的字串,包含小寫字母和問號"?",是按照橫座標遞增的順序的每個點的描述。問號表示這個點的字母被petya擦掉了。保證輸入串不含字母"x"。

輸出格式

輸出答案對4294967296取模的值。如果沒有可行的方案,輸出0。

樣例輸入

4a???

樣例輸出

樣例輸入

4abc?

樣例輸出

樣例輸入

6abc???

樣例輸出

資料規模和約定

20個測試點的n分別為:

5,10,20,50,100,

200,500,1000,2000,5000,

10000,20000,30000,40000,50000,

60000,70000,80000,90000,100000.

n為奇數,直接輸出0返回

字元"?"的個數大於n/2,直接輸出0返回

計算小寫字母被擦掉的個數num

用num層遞迴(dfs)列舉可能是小寫字母的位置——太暴力(可優化點,改迴圈就可以)

匹配字母——從字串的最後乙個小寫字母的位置開始,向右找到最近的乙個"?",將這個小寫字母和最近的"?「變為"0」,表示已配對,重複這個過程,一旦有乙個小寫字母右邊沒有可以配對的"?"表示配對失敗,否則匹配完了就配對成功

每匹配成功一次 計數器自增一次

輸出計數器的值

計算所有相鄰的字元可配對的數,具體計算方法(f(x,y))如下:"##"=0,"?#"=0,"#?"=1,"??"=25

計算間隔2r自小向大(每次加2)計算範圍(i,i+2r+1)內字元可以配對的組合數,組合數record[r][i]=f(i,i+2*k+1)*record[k][i+1]*record[r-k-1]i+2*k+2

輸出record[r][0]得到答案

記憶體優化:二維表變倒金字塔表

#include

#include

#define max 100000

#define mod 4294967296

using

namespace std;

char

*str;

long

long

**record;

//計算配對數

long

longf(

int x,

int y)

intmain()

//3.初始化記事本

record=

newlong

long

*[n/2]

;for

(int i=

0;i) record[i/2]

=new

long

long

[n-1

-i];

for(

int i=

0;i1;i++

) record[0]

[i]=

f(i,i+1)

;//4.填充記事本

int r;

long

long t;

for(

int len=

3;len<=n-

1;len+=2

) record[r]

[i]=

f(i,i+len)

*record[r-1]

[i+1];

record[r]

[i]%

=mod;

t=1;

for(

int k=

0;k}// for(int i=0;i

// for(int j=0;j

// cout// cout//5.輸出結果

cout<1][0

];for(

int i=

0;i2;i++

)delete record[i]

;delete record;

delete str;

return0;

}

用f[i] [j]表示在第i個位置已經確定了j個大寫字母的組合數

在第f[i] [j]個位置可能由f[i-1] [j]得到(此時第i個位置填的是小寫字母,第i-1以內本來就確定j個大寫字母),也可能由f[i-1] [j-1]得到(此時第i個位置填的是大寫字母,第i-1內就確定了j-1個大寫字母)

遞推公式:綜上有f[i] [j]=f[i-1] [j-1]+f[i-1] [j]

假設字串長度為n,最後在f[n] [n/2]位置儲存的就是在第n個位置確定了n/2個大寫字母的合理組合數

計算被擦掉的小寫字母個數may,由於每種合理的組合都含有may個沒確定的小寫字母,每個小寫字母都可能是25個字母(除去了x)中的乙個,故25^may * f[n] [n/2]就是結果

空間優化(滾動陣列):該問題最大規模是n=100000,明顯乙個100000*50000的陣列會超記憶體,但是注意到每個格仔都僅僅依賴於上一行的結果,因此所有結果可以使用滾動陣列去覆蓋掉上一層結果,節省記憶體

#include

#include

using

namespace std;

intmain()

int may=n2-p;

for(

int i=

0;i) f[n2]*=

25;//每有乙個被擦掉的小寫字母就翻25倍

printf

("%u"

,f[n2]);

return0;

}

DL RBM訓練演算法

在學習hinton的stack autoencoder演算法 reducing the dimensionality of data with neural networks 之前需要了解什麼是rbm,現在就我學習的情況,查詢的資料 大部分來自部落格 簡單介紹一下rbm。當然,這裡面還有同組實驗的同...

演算法訓練 C Calculations

問題描述 c 語言和c 語言非常相似,然而c 的程式有時會出現意想不到的結果。比如像這樣的算術表示式 表示式 基本式 表示式 基本式 表示式 基本式 基本式 增量 係數 增量 增量 a a 係數 0 1 2 1000 如 5 a 3 a a 是合法的c 表示式。計算這樣的表示式的值的方法 首先是每個...

演算法訓練 暗戀

演算法訓練 暗戀 時間限制 1.0s 記憶體限制 256.0mb 問題描述 同在乙個高中,他卻不敢去找她,雖然在別人看來,那是再簡單不過的事。暗戀,是他唯一能做的事。他只能在每天課間操的時候,望望她的位置,看看她傾心的動作,就夠了。操場上的彩磚啊,你們的位置,就是他們能夠站立的地方,他倆的關係就像磚...