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

1996: [Hnoi2010]chorus 合唱队

时间:2017-10-20 21:43:08      阅读:215      评论:0      收藏:0      [点我收藏+]

标签:bsp   相对   image   break   序列   online   sample   一个   mst   

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;
}

 

1996: [Hnoi2010]chorus 合唱队

标签:bsp   相对   image   break   序列   online   sample   一个   mst   

原文地址:http://www.cnblogs.com/renjianshige/p/7701410.html

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