• 1996: [Hnoi2010]chorus 合唱队


    1996: [Hnoi2010]chorus 合唱队

    Time Limit: 4 Sec  Memory Limit: 64 MB
    Submit: 1850  Solved: 1197
    [Submit][Status][Discuss]

    Description

    Input

    Output

    Sample Input

    4
    1701 1702 1703 1704

    Sample Output

    8

    HINT

     

     
    题解:
      这个题目,首先分析一下题目的性质,对于一个排列,我们要保证可以形成最终的序列,那么就必须要保证他们的相对位置不变,看一下数据范围n^2,就可以知道这个题目应该要记一下当前dp的左右端点。
      当然,发现这样并不能转移,发现对于一个元素,如果处理到当前为的答案序列已经确定,他前面的数确定,那么他的位置也是确定的,所以还要记一下他当前前面的是谁,所以设dp[i][j]0/1]表示已经形成了答案串的i~j部分,上一个点是i还是j的方案数,转移十分简单。注意初始化的时候只能初始话一边(至于为什么博主也不知道,只是知道如果初始化两边,就会是答案的两倍,然后还要拓展欧几里德求逆)。
     
    代码:
    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cmath>
    #include <iostream>
    #define MAXN 1100
    #define mod 19650827
    #define ll long long
    using namespace std;
    ll dp[MAXN][MAXN][2];
    int n,h[MAXN];
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&h[i]);
        for(int i=1;i<=n;i++) dp[i][i][0]=1;
        for(int len=2;len<=n;len++)
            for(int i=1;i<=n;i++){
                int j=i+len-1;if(j>n) break;
                if(h[i]<h[i+1]) dp[i][j][0]=dp[i][j][0]+dp[i+1][j][0];
                if(h[i]<h[j]) dp[i][j][0]=dp[i][j][0]+dp[i+1][j][1];
                if(h[j]>h[i]) dp[i][j][1]=dp[i][j][1]+dp[i][j-1][0];
                if(h[j]>h[j-1]) dp[i][j][1]=dp[i][j][1]+dp[i][j-1][1];
                if(dp[i][j][0]>=mod) dp[i][j][0]-=mod;
                if(dp[i][j][1]>=mod) dp[i][j][1]-=mod;
            }
        printf("%lld",(dp[1][n][0]+dp[1][n][1])%mod);
        return 0;
    }
  • 相关阅读:
    函数进阶-生成器
    函数进阶-列表生成式
    闭包
    命名空间
    内置方法
    函数
    squid清除缓存
    subprocess实现管道
    Python统计脚本行数(fileinput)
    fabric note
  • 原文地址:https://www.cnblogs.com/renjianshige/p/7701410.html
Copyright © 2020-2023  润新知