码迷,mamicode.com
首页 > 其他好文 > 详细

ZOJ 3892 Available Computation Sequence 区间dp

时间:2015-09-17 15:13:39      阅读:153      评论:0      收藏:0      [点我收藏+]

标签:

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5595

 

题意:给出n个字符串,里面包含‘*‘, ‘.‘, ‘^‘, ‘!‘这四个运算符,以及小写字母(表示向量)和数字。

四个运算符都有不同的运算规则。问添上括号后,可以组成多少个不同的算式(不能进行非法运算)。

 

思路:简单区间DP,把一个运算符看成一位。

dp[i][j][1]表示第i-j位运算结果为数字的情况有多少种。

dp[i][j][0]表示第i-j位运算结果为向量的情况有多少种。

然后进行区间DP,根据中间的运算符选择两边是数字或者向量,避免非法情况。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int T;
 4 string s;
 5 long long dp[200][200][2];
 6 char op[110];
 7 int mark[110];
 8 const long long mod = 1000000000+7;
 9 int main()
10 {
11     scanf("%d", &T);
12     while(T--)
13     {
14         cin>>s;
15         bool fop = false;
16         int cntop = 0, cnt = 0;
17         for(int i = 0; i < s.size(); i++)
18         {
19             if(i == 0)
20             {
21                 if(s[0] >= 0 && s[0] <= 9) mark[++cnt] = 1;        
22                 else if(s[0] >= a && s[0] <= z) mark[++cnt] = 0;            
23             }
24             else
25             {
26                 if(s[i] == ^ || s[i] == ! || s[i] == * || s[i] == .)
27                 {
28                     fop = true;
29                     op[++cntop] = s[i];
30                 }
31                 else
32                 {
33                     if(fop == true)
34                     {
35                         if(s[i] >= 0 && s[i] <= 9) mark[++cnt] = 1;
36                         else if(s[i] >= a && s[i] <= z) mark[++cnt] = 0;        
37                         fop = false;
38                     }
39                     else continue;
40                 }
41             }
42 
43         }
44         memset(dp, 0, sizeof(dp));
45         for(int i = 1; i <= cnt; i++) 
46         {    
47             if(mark[i] == 0) dp[i][i][0] = 1;
48             else if(mark[i] == 1) dp[i][i][1] = 1;
49         }
50 
51         for(int len = 2; len <= cnt; len++)
52         {
53             for(int i = 1; i <= cnt-len+1; i++)
54             {
55                 int j = i+len-1;
56                 for(int k = i; k < j; k++)
57                 {
58                     if(op[k] == *)
59                     {
60                         dp[i][j][0] += (dp[i][k][1]*dp[k+1][j][0]%mod+dp[i][k][0]*dp[k+1][j][1]%mod);
61                         dp[i][j][0]    %= mod;
62                         dp[i][j][1] += dp[i][k][1]*dp[k+1][j][1]%mod;
63                         dp[i][j][1] %= mod;
64                     }
65                     else if(op[k] == ^)
66                     {
67                         dp[i][j][0] += dp[i][k][0]*dp[k+1][j][0]%mod;
68                         dp[i][j][0] %= mod;
69                     }
70                     else if(op[k] == .)
71                     {
72                         dp[i][j][1] += dp[i][k][0]*dp[k+1][j][0]%mod;
73                         dp[i][j][1] %= mod;
74                     }
75                     else if(op[k] == !)
76                     {
77                         dp[i][j][1] += dp[i][k][0]*dp[k+1][j][0]%mod;
78                         dp[i][j][1] %= mod;
79                         dp[i][j][0] += dp[i][k][0]*dp[k+1][j][1]%mod + dp[i][k][1]*dp[k+1][j][0]%mod
80                             + dp[i][k][1]*dp[k+1][j][1]%mod;
81                         dp[i][j][0] %= mod;
82                     }
83                 }
84             }
85         }
86         long long ans = (dp[1][cnt][0] + dp[1][cnt][1])%mod;
87         printf("%lld\n", ans);
88 
89 
90     }
91     return 0;
92 }

 

ZOJ 3892 Available Computation Sequence 区间dp

标签:

原文地址:http://www.cnblogs.com/titicia/p/4816268.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!