ZOJ 3543 Number String

来源:互联网 发布:网络推广对企业的意义 编辑:程序博客网 时间:2024/05/16 06:01

大连赛区现场赛的E题。经典的简单DP。

设状态f[i][j]表示到达第i位以j结尾的方案数,则状态转移方程为:

如果为‘D’ 或者 ‘?’   则:f[i][j] += sum(f[i-1][k]),  j<=k<i

如果为'I'或者‘?’,  则:f[i][j] += sum(f[i-1][k]),  1<=k<j

最后统计一下就好了,这是个O(n^3)的算法,很显然地用部分和的思想优化一下就变成了O(n^2)的了。

PS:十分膜拜watashi大神的报告中的STL写法,太强大了.....

#include <iostream>#include <cstdio>#include <string>#include <cstring>#define Maxn 1010using namespace std;const int mod = 1000000007;string s;int f[Maxn][Maxn], n, ans;int sum[Maxn][Maxn];int main(){    while (getline(cin, s))    {          memset(f, 0, sizeof(f));          memset(sum, 0, sizeof(sum));          f[0][0] = 1;          n = s.length();          for (int i=1; i<=n; i++) sum[0][i] = 1;          for (int i=1; i<=n; i++)          {              for (int j=1; j<=i+1; j++)              {                  if (s[i-1] == 'I' || s[i-1] == '?')                  {                      f[i][j] += sum[i-1][j-1];                                               }                  if (s[i-1] == 'D' || s[i-1] == '?')                  {                      f[i][j] += (sum[i-1][i] - sum[i-1][j-1]);                      f[i][j] = (f[i][j] + mod) % mod;                                               }                  sum[i][j] = (sum[i][j-1] + f[i][j]) % mod;                 }                        }          ans = 0;          for (int i=0; i<=n+1; i++) ans = (ans + f[n][i]) % mod;          cout <<ans <<endl;             }    return 0;    }