CF 106 div 2 乘法dp 字尾自動機)

2021-09-11 14:21:10 字數 1554 閱讀 5421

比賽連線 d

簡單區間dp

乙個合法的括號序列染色,一對匹配的括號必須有乙個被染成紅色或者藍色,另乙個不染色。

被染色的相鄰括號不能相同顏色,問有幾種染色的方法。

直接區間dp,轉移就是考慮每種情況然後相乘就可以了。

#include#include#define mod 1000000007

using namespace std;

char s[1000];

int p[1000];

long long dp[3][3][705][705];

int main()

} memset(dp,0,sizeof(dp));

for (int i=2;i<=len;i++)}}

}}

else if (m==r)

else}}

} }

}} }

long long ans=0;

for (int i=0;i<3;i++)

} cout字尾自動機

其實還是不太會這個東西,又看了一遍clj老師的講稿,但是這題的應用確實還蠻基礎的。

正反建兩個字尾自動機,然後對於每個字串匹配最優的情況就可以了。

#include#include#include#define n 100005

#define inf 0x3f3f3f3f

using namespace std;

char s[n];

char s1[1005];

int n;

char text[n];

struct state

};struct suffixautomaton

if (p==0) np->par=root;

else

else

}} last=np;

np->f=true;

} void work(state* now, int dep)

} if (now->f) now->fst=min(now->fst, now->val);

now->vis=true;

return;

} void init(char *s)

//for (int i=0;i<26;i++) coutelse

} }}a,b;

int a[1005],b[1005];

int main(){

scanf("%s",s+1);

a.init(s);

int len=strlen(s+1);

reverse(s+1,s+len+1);

b.init(s);

scanf("%d",&n);

int ans=0;

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

scanf("%s",s1+1);

int len1=strlen(s1+1);

if (len1==1) continue;

a.match(s1,a);

/*for (int i=1;i<=len1;i++){

cout《字串

CF 284 Div 2 C (幾何規律)

解題思路 把兩個點的座標分別帶入方程組,如果最後兩個值相乘為負,即異號,計數器 其中有乙個有趣的現象,從a到b的最短步數,可以變化為求a和b之間夾了多少條直線,那麼最後只要求出直線數,即可求出最小步數。如果一條直線夾在a和b中間,那麼把a和b的座標帶入後,所得值相乘一定為負。資料很大,中間還涉及乘法...

CF444 Div 1簡單題解

題意 給定帶點權和邊權的無向圖,現在讓你選一些點,使得 點權和 被選點對間的邊權和 最大。思路 不難證明,選擇邊和對應的兩點是最優的。include define rep i,a,b for int i a i b i using namespace std const int maxn 20001...

CF453 Div1 簡單題解

pro 給定m,n,表示乙個m面的骰子,甩n次,問出現的最大的數的期望。sol 容斥,f i 表示最大數 i的期望,那麼最大數 x的期望就是f x f x 1 include define rep i,a,b for int i a i b i using namespace std const i...