首页 > 其他 > 详细

T - Permutation 题解(思维+dp)

时间:2020-11-25 22:47:37      阅读:42      评论:0      收藏:0      [点我收藏+]

题目链接

题目大意

给你一个数字n和长为n-1个字符串

字符串包含‘<‘,‘>‘

若s[i]=‘<‘ 则代表a[i]<a[i+1]

若s[i]=‘>‘ 则代表a[i]>a[i+1]

你要构造一个长度为n的全排列,使其满足条件

求方案数mod 1e9+7

题目思路

这个问题主要就是不知道如何保证自己构造的数组是一个全排列

又是一个神仙dp,

\(dp[i][j]\)代表[1,i]为全排列,且第i个元素为j

那么该怎么转移。

若为‘<‘ \(dp[i][j]=\sum_{t=1}^{t=j-1} dp[i-1][t]\)

若为‘>’ \(dp[i][j]=\sum_{t=j}^{t=n} dp[i-1][t]\)

这个转移实属神奇,把j放到i-1个全排列后面,然后前i-1中大于等于j的元素全部加1即可

这样前i个元素又满足全排列,最后一个元素还是j,满足转移方程

然后前缀和优化即可,注意j<=i

代码

#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<vector>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#define fi first
#define se second
#define debug printf(" I am here\n");
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
const ll INF=0x3f3f3f3f3f3f3f3f;
const int maxn=3e3+5,inf=0x3f3f3f3f,mod=1e9+7;
const double eps=1e-10;
int n,flag[maxn];
char s[maxn];
ll dp[maxn][maxn],pre[maxn][maxn];
int main(){
    scanf("%d %s",&n,s+1);
    for(int i=1;i<=n-1;i++){
        if(s[i]==‘<‘){
            flag[i]=1;
        }else{
            flag[i]=0;
        }
    }
    dp[1][1]=1;
    for(int i=1;i<=n;i++){
        pre[1][i]=1;
    }
    for(int i=2;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(j>i){
                pre[i][j]=pre[i][j-1];
                continue;
            }
            if(flag[i-1]){
                dp[i][j]=pre[i-1][j-1]%mod;
            }else{
                dp[i][j]=((pre[i-1][n]-pre[i-1][j-1])%mod+mod)%mod;
            }
            pre[i][j]=(pre[i][j-1]+dp[i][j])%mod;
        }
    }
    printf("%lld\n",pre[n][n]);
    return 0;
}

T - Permutation 题解(思维+dp)

原文:https://www.cnblogs.com/hunxuewangzi/p/14038923.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!