CodeForces 149D Coloring Brackets

来源:http://www.cnblogs.com/Silenceneo-xw/archive/2016/10/07/5936579.html
-Advertisement-
Play Games

Coloring Brackets time limit per test: 2 seconds time limit per test: 2 seconds memory limit per test: 256 megabytes memory limit per test: 256 megaby ...


Coloring Brackets

time limit per test: 2 seconds memory limit per test: 256 megabytes input: standard input output: standard output

Once Petya read a problem about a bracket sequence. He gave it much thought but didn't find a solution. Today you will face it.

You are given string s. It represents a correct bracket sequence. A correct bracket sequence is the sequence of opening ("(") and closing (")") brackets, such that it is possible to obtain a correct mathematical expression from it, inserting numbers and operators between the brackets. For example, such sequences as "(())()" and "()" are correct bracket sequences and such sequences as ")()" and "(()" are not.

In a correct bracket sequence each bracket corresponds to the matching bracket (an opening bracket corresponds to the matching closing bracket and vice versa). For example, in a bracket sequence shown of the figure below, the third bracket corresponds to the matching sixth one and the fifth bracket corresponds to the fourth one.

You are allowed to color some brackets in the bracket sequence so as all three conditions are fulfilled:

  • Each bracket is either not colored any color, or is colored red, or is colored blue.
  • For any pair of matching brackets exactly one of them is colored. In other words, for any bracket the following is true: either it or the matching bracket that corresponds to it is colored.
  • No two neighboring colored brackets have the same color.

Find the number of different ways to color the bracket sequence. The ways should meet the above-given conditions. Two ways of coloring are considered different if they differ in the color of at least one bracket. As the result can be quite large, print it modulo 1000000007 (109 + 7).

Input

The first line contains the single string s (2 ≤ |s| ≤ 700) which represents a correct bracket sequence.

Output

Print the only number — the number of ways to color the bracket sequence that meet the above given conditions modulo 1000000007 (109 + 7).

Examples

Input

(())

Output

12

Input

(()())

Output

40

Input

()

Output

4

Note

Let's consider the first sample test. The bracket sequence from the sample can be colored, for example, as is shown on two figures below.

The two ways of coloring shown below are incorrect.

題目大意:給定一個合法的括弧序列,現在要你給括弧序列染色。但是必須要滿足如下條件:一、一個括弧可以不染色,或者染紅色,或者染藍色;二、一對匹配的括弧只能有一邊染色(這裡的匹配是唯一的對應,而不是只要是"()"就可,下同),且必須有一邊染色;三、相鄰的括弧染的顏色必須不一樣,但是可以都不染色。問你有多少種方案?因為方案數很大,所以結果模去1e9+7。

 

解題思路:容易看出這是一道DP題,並且是一道區間DP題。自己的DP很差,想了半天沒想出來。於是去網上搜了一下別人的解法,瞬間恍然大悟了。設dp[l][r][x][y]表示區間[l,r]左端染的色是x,右端染的色是y的方案數,其中x,y取0,1,2,分別表示不染色,染紅色,染藍色。則該區間有三種情況,如下:

1、l+1==r,那麼它們一定就是一對匹配的括弧,此時,只可能有四種情況,方案數均為1,即:dp[l][r][0][1] = dp[l][r][1][0] = 1;dp[l][r][0][2] = dp[l][r][2][0] = 1;

2、l和r是一對匹配的括弧,此時,區間被分為兩部分,兩端點以及區間[l+1,r-1],那麼我們可以先算出區間[l+1,r-1]的方案數,再由此狀態轉移到當前區間,兩端點情況也就四種,不衝突即可轉移,詳見代碼;

3、l和r不是一對匹配的括弧,此時,區間也可被分成兩部分,區間[l,mid]和區間[mid+1,r],其中mid為l所對應與之匹配的括弧,這樣,一個合法的括弧序列變成兩個合法的括弧序列,將它們分別求出方案數,再將不衝突的情況組合起來即可,詳見代碼。

 

附上AC代碼:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn = 705;
 5 const int mod = 1000000007;
 6 ll dp[maxn][maxn][3][3];
 7 string str;
 8 stack<int> s;
 9 map<int, int> pos;
10 
11 void get_match(){
12     for (int i=0; i<str.size(); ++i){
13         if (str[i] == '(')
14             s.push(i);
15         else{
16             pos[i] = s.top();
17             pos[s.top()] = i;
18             s.pop();
19         }
20     }
21 }
22 
23 void dfs(int l, int r){
24     if (l+1 == r){
25         dp[l][r][0][1] = dp[l][r][1][0] = 1;
26         dp[l][r][0][2] = dp[l][r][2][0] = 1;
27         return ;
28     }
29     if (pos[l] == r){
30         dfs(l+1, r-1);
31         for (int i=0; i<3; ++i)
32             for (int j=0; j<3; ++j){
33                 if (j != 1)
34                     dp[l][r][0][1] = (dp[l][r][0][1]+dp[l+1][r-1][i][j])%mod;
35                 if (j != 2)
36                     dp[l][r][0][2] = (dp[l][r][0][2]+dp[l+1][r-1][i][j])%mod;
37                 if (i != 1)
38                     dp[l][r][1][0] = (dp[l][r][1][0]+dp[l+1][r-1][i][j])%mod;
39                 if (i != 2)
40                     dp[l][r][2][0] = (dp[l][r][2][0]+dp[l+1][r-1][i][j])%mod;
41             }
42         return ;
43     }
44     int mid = pos[l];
45     dfs(l, mid);
46     dfs(mid+1, r);
47     for (int i=0; i<3; ++i)
48         for (int j=0; j<3; ++j)
49             for (int k=0; k<3; ++k)
50                 for (int s=0; s<3; ++s)
51                     if (!(k==1&&s==1) && !(k==2&&s==2))
52                         dp[l][r][i][j] = (dp[l][r][i][j]+dp[l][mid][i][k]*dp[mid+1][r][s][j])%mod;
53 }
54 
55 int main(){
56     ios::sync_with_stdio(false);
57     cin.tie(0);
58     cin >> str;
59     get_match();
60     dfs(0, str.size()-1);
61     ll ans = 0;
62     for (int i=0; i<3; ++i)
63         for (int j=0; j<3; ++j)
64             ans = (ans+dp[0][str.size()-1][i][j])%mod;
65     cout << ans << endl;
66     return 0;
67 }
View Code

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 為什麼要引入繼承?   還是做一個媒體庫,裡面可以放CD,可以放DVD。如果把CD和DVD做成兩個沒有聯繫的類的話,那麼在管理這個媒體庫的時候,要單獨做一個添加CD的函數,單獨做一個添加DVD的函數,如果還要往這個媒體庫里添加其他的媒體類,還要再創建另一個添加函數。我們說這樣的代碼不具備可擴展性。... ...
  • 收集整理一些常用的PHP類庫,資源以及技巧. 有中英兩種版本,以便在工作中迅速的查找所需。 ...
  • 在我前面的文章(http://www.cnblogs.com/homewch/p/5749850.html)中有提到R可以自定義啟動環境,需要修改R安裝文件中的ect文件夾下的配置文件Rprofile.site即可: Rprofile.site文件里,設置的內容包括預設編輯器,CRAN鏡像選取,自動 ...
  • Python 學習之路 目錄介紹 一、Python 介紹 python的創始人是吉多·範羅蘇姆.Python於1989年的聖誕節期間誕生. 二、Python 的主要應用領域 雲計算:OpenStack是python語言開發的 web開發:典型web框架有Django 科學運算\人工智慧:典型庫Num ...
  • Brackets Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 6622 Accepted: 3558 Description We give the following inductive definition of a “r ...
  • MySql簡單操作 JDBC JDBC驅動程式分為4類 JDBC ODBC橋 部分本地API,部分Java驅動程式 JDBC網路純Java驅動程式 本地協議Java驅動程式 JDBC的示例 建立一個test case來驗證一下 執行結果 ...
  • 合併排序 1. 演算法思想 對於輸入的數組a[i , j],將其分為大致相同的2個子集,利用遞歸一直分下去,然後分別對2個子集進行排序(在合併中體現),最終完成排序。 2. 演算法實現 3. 演算法分析 在Merge排序中,其時間複雜度與輸入數組是否有序無關,最壞時間複雜度和平均時間複雜度均為Ο(nlog ...
  • struts2 Java Web開發環境 1、安裝jdk 2、安裝tomcat 3、配置環境 "Java Web環境配置" Web工程 新建一個web工程,工程名為WebappTest 導入struts2的基礎jar包 編寫Action類和配置文件 編寫action類 編寫action處理後跳轉的j ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...