• BZOJ1996 [Hnoi2010]chorus 合唱队


    很容易想到区间DP

    然后发现这个区间只和圆序列的最后一个数有关,而原序列的最后一个数只可能是现在区间的头或者尾

    令$f[i][j][0/1]$表示在区间$[i, j]$之间,原序列的最后一个数是当前区间的头/尾的总答案数

    于是只要讨论$a[i], a[i + 1], a[j - 1], a[j]$之间的关系搞一搞就可以了

     1 /**************************************************************
     2     Problem: 1996
     3     User: rausen
     4     Language: C++
     5     Result: Accepted
     6     Time:112 ms
     7     Memory:8700 kb
     8 ****************************************************************/
     9  
    10 #include <cstdio>
    11 #include <cstring>
    12   
    13 using namespace std;
    14 const int N = (int) 1e3 + 5;
    15 const int mod = 19650827;
    16   
    17 int n, a[N];
    18 int f[N][N][2], ans;
    19   
    20 int main() {
    21     int i, j, len;
    22     scanf("%d", &n);
    23     if (n == 1) {
    24         puts("1");
    25         return 0;
    26     }
    27     for (i = 1; i <= n; ++i) scanf("%d", a + i);
    28     for (i = 1; i < n; ++i)
    29         f[i][i + 1][0] = f[i][i + 1][1] = bool(a[i] < a[i + 1]);
    30     for (len = 3; len <= n; ++len)
    31         for (i = 1; i <= n - len + 1; ++i) {
    32             j = i + len - 1, f[i][j][0] = f[i][j][1] = 0;
    33             if (a[j] > a[j - 1]) f[i][j][1] += f[i][j - 1][1];
    34             if (a[j] > a[i]) f[i][j][1] += f[i][j - 1][0];
    35             if (a[i] < a[i + 1]) f[i][j][0] += f[i + 1][j][0];
    36             if (a[i] < a[j]) f[i][j][0] += f[i + 1][j][1];
    37             f[i][j][0] %= mod, f[i][j][1] %= mod;
    38         }
    39     ans = (f[1][n][0] + f[1][n][1]) % mod;
    40     printf("%d
    ", ans);
    41     return 0;
    42 }
    View Code
  • 相关阅读:
    four day (linux基础学习1)
    three day(网络基础)
    two day(操作系统)
    Oldboy One day(计算机基础)
    mybatis调用存储过程
    调用jiathis分享接口
    汉字转换拼音工具类
    Ajax前后台交互 返回普通格式和JSON格式
    Bootstrap与EasyUI入门
    MD5,sha1加密工具类
  • 原文地址:https://www.cnblogs.com/rausen/p/4508919.html
Copyright © 2020-2023  润新知