BZOJ 1925 地精部落(DP)

一道很经典的DP题。

题意:求n排列中波动排列的种数。

不妨考虑DP,令dp1[i][j],表示1-j的排列中,第一项为i之后递增的波动排列种数。dp2[i][j]表示1-j的排列中,第一项为i之后递减的波动排列种数。

显然有一个性质,dp1[i][j]=dp2[j+1-i][j],将各项用j+1减去即可。

所以我们主要观察dp1数组。

如果第一项放了i,之后的数字是1,2,,,i-1,i+1,i+2,,j。

如果我们把大于i的数减去1,就又变成了j-1的一个排列,那么则有dp1[i][j]=sum(dp2[i][j-1]+dp2[i+1][j-1]+...dp2[j-1][j-1]).

因为dp2[i][j]=dp1[j+1-i][j],所以dp1[i][j]=sum(dp1[1][j-1]+dp1[2][j-1]+....+dp1[j-i][j-1]).

可以用前缀和优化转移。用滚动数组优化空间。时间复杂度O(n^2).

# include <cstdio>
# include <cstring>
# include <cstdlib>
# include <iostream>
# include <vector>
# include <queue>
# include <stack>
# include <map>
# include <bitset>
# include <set>
# include <cmath>
# include <algorithm>
using namespace std;
# define lowbit(x) ((x)&(-x))
# define pi acos(-1.0)
# define eps 1e-8
# define MOD 1000000007
# define INF 1000000000
# define mem(a,b) memset(a,b,sizeof(a))
# define FOR(i,a,n) for(int i=a; i<=n; ++i)
# define FO(i,a,n) for(int i=a; i<n; ++i)
# define bug puts("H");
# define lch p<<1,l,mid
# define rch p<<1|1,mid+1,r
# define mp make_pair
# define pb push_back
typedef pair<int,int> PII;
typedef vector<int> VI;
# pragma comment(linker, "/STACK:1024000000,1024000000")
typedef long long LL;
int Scan() {
    int x=0,f=1;char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
    return x*f;
}
const int N=4205;
//Code begin...

int dp[2][N], sum[N];

int main ()
{
    int n, P, flag=0;
    scanf("%d%d",&n,&P);
    dp[0][1]=1; sum[1]=1;
    for (int i=n-1; i>=1; --i) {
        flag^=1; mem(dp[flag],0);
        FOR(j,1,n-i+1) if (n-i-j>=0) dp[flag][j]=sum[n-i-j+1];
        mem(sum,0);
        FOR(j,1,n-i+1) sum[j]=(sum[j-1]+dp[flag][j])%P;
    }
    LL ans=0;
    FOR(i,1,n) ans=(ans+dp[flag][i])%P;
    ans=ans*2%P;
    printf("%lld\n",ans);
    return 0;
}

时间: 2024-11-05 02:36:37

BZOJ 1925 地精部落(DP)的相关文章

BZOJ 1925 地精部落(DP)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1925 题意:求1到n个所有排列中有多少种满足高低交错. 思路:f[n][k]表示n个数,最后一个为k且最后两个递增,g[n][k]表示n个数最后一个数为k且最后两个递减.对于f[n][k],若我们将每个数x换为n+1-x,则就成了g[n][n+1-k],因此有:f[n][k]=g[n][n+1-k].那么可得: 由于对称性,我们计算出: 那么最后的答案就是2ans. i64 f[2][

BZOJ 1925: [Sdoi2010]地精部落( dp )

和几天前校内的某场NOIP模拟赛T3一模一样... dp(i,j)表示1~i的排列中, 以1~j为开头且开头是下降的合法方案数 这种数列具有对称性, 即对于一个满足题意且开头是上升的n的排列{an}, 令bn = n-an+1, 那么{bn}就是一个满足题意且开头是下降的序列 dp(i,j) = dp(i,j-1) + dp(i-1,i-j+1). 前一个好理解, 就是求排列i, 1~j-1开头的, 后一种就是求以j开头, 那么原来的排列i-1应该以1~j-1开头, 但是开头又得是上升的(这样加

【BZOJ】1925: [Sdoi2010]地精部落 DP+滚动数组

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1925 题意:输入一个数N(1 <= N <= 4200),问将这些数排列成折线型有多少中合法的排列:折线形即一个数比相邻的数都大或者都小; 如:1 3 2 4就是一个折线型: 思路:f[i,j]表示排列的前i个数是以1...j为开头的第一位下降的合法个数: 转移公式为:f[i][j] = f[i][j-1] + f[i-1][i-j]; f[i][j-1]就不把第j个数添加到首位的原来

1925: [Sdoi2010]地精部落 dp, 抖动子序列

看到这道题第一反应就把该题与白书的一道例题联系起来了.(虽然后来证明两者并没有联系.)因此我一开始的思路就是从n到1一个个加进去.虽然的确搞不太出来. 然后开始膜题解了.………………………………好可耻啊! 首先可以证明.一个开头下降的抖动子序列 1~n 可以通过 n - xi + 1 (xi 为 第i位的值 )的形式变为一个上升的. 然后就利用这个性质搞了 设 f[i][j] 为长度为 i , 分别以 1~j 开头且开头上升(如果你要问我为什么是上升的你可以自己推一下,反正我推不出来.)的方案数

bzoj1925: [Sdoi2010]地精部落 [dp]

Description 传说很久以前,大地上居住着一种神秘的生物:地精. 地精喜欢住在连绵不绝的山脉中.具体地说,一座长度为 N 的山脉 H可分 为从左到右的 N 段,每段有一个独一无二的高度 Hi,其中Hi是1到N 之间的正 整数. 如果一段山脉比所有与它相邻的山脉都高,则这段山脉是一个山峰.位于边 缘的山脉只有一段相邻的山脉,其他都有两段(即左边和右边). 类似地,如果一段山脉比所有它相邻的山脉都低,则这段山脉是一个山谷. 地精们有一个共同的爱好——饮酒,酒馆可以设立在山谷之中.地精的酒馆

wxy和zdy眼中的水题 地精部落 dp

题目描述 传说很久以前,大地上居住着一种神秘的生物:地精. 地精喜欢住在连绵不绝的山脉中.具体地说,一座长度为 N 的山脉 H可分 为从左到右的 N 段,每段有一个独一无二的高度 Hi,其中Hi是1到N 之间的正 整数. 如果一段山脉比所有与它相邻的山脉都高,则这段山脉是一个山峰.位于边 缘的山脉只有一段相邻的山脉,其他都有两段(即左边和右边). 类似地,如果一段山脉比所有它相邻的山脉都低,则这段山脉是一个山谷. 地精们有一个共同的爱好——饮酒,酒馆可以设立在山谷之中.地精的酒馆 不论白天黑夜总

P2467 [SDOI2010]地精部落 DP

传送门:https://www.luogu.org/problemnew/show/P2467 参考与学习:https://www.luogu.org/blog/user55639/solution-p2467 题意: 求波动数列 思路: 设dp[i][j] 表示长度为i, 开始位子为j, 且开始位子是波峰. 首先这个波动数列有一些性质: 1: 在一个波动数列中,若两个 i 与 i+1 不相邻,那么我们直接交换这两个数字就可以组成一个新的波动数列: 举个栗子: 5 2 3 1 4 2: 把波动数

luogu2467/bzoj1925 地精部落 (dp)

求1~n组成一个抖动序列的方案数 首先这种序列有一些非常妙妙但我发现不了的性质 1.对于一个抖动序列,如果i和i+1不相邻,则交换i和i+1,他还是个抖动序列 2.对于一个抖动序列,我把每个数拿n+1减一下(上下翻转),他还是个抖动序列,只不过波峰和波谷换了一下 3.对于一个抖动序列,我把它左右翻转,他还是个抖动序列 于是设f[i][j]是i个数中,排名为j的数在第一个位置.且它是波峰的方案数 那么答案就是$2\sum{f[N][i]}$(我把它翻一下不就有所有的第一个数作为波谷的情况了嘛) 然

[BZOJ 1925][Sdoi2010]地精部落

1925: [Sdoi2010]地精部落 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1468  Solved: 918[Submit][Status][Discuss] Description 传说很久以前,大地上居住着一种神秘的生物:地精. 地精喜欢住在连绵不绝的山脉中.具体地说,一座长度为 N 的山脉 H可分 为从左到右的 N 段,每段有一个独一无二的高度 Hi,其中Hi是1到N 之间的正 整数. 如果一段山脉比所有与它相邻的山脉都高,则这